﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using NPOI.XWPF.UserModel;
using System.Drawing;
using NPOI.OpenXmlFormats.Wordprocessing;
using LunarSF.SHomeWorkshop.LunarMarkdownEditor;
using System.Windows;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// 用以提取指定编辑器中的试题文本或生成 Word 文档。
    /// </summary>
    public class QuestionBuilder
    {
        public static List<Question> BuildQuestions(string filePath, StringBuilder errorMsg)
        {
            if (errorMsg == null)
                errorMsg = new StringBuilder();

            if (System.IO.File.Exists(filePath) == false)
            {
                errorMsg.Append("未提供有效文件名。");
                return null;
            }

            var content = System.IO.File.ReadAllText(filePath);

            content = CustomMarkdownSupport.CompilePrototypeChoiceExams(content);

            // 去除一些特殊的行： ！ ； \[a-z] 开头的行。

            string[] lines = content.Split(new string[] { "\r\n", }, StringSplitOptions.None);
            var sb = new StringBuilder();
            Regex regIgnore = new Regex(@"^(([?？;；:：%])|(\\[a-zA-Z][ 　\t]{1,}))");
            foreach (var line in lines)
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    sb.Append("\r\n");
                    continue;
                }

                if (regIgnore.Match(line).Success)
                    continue;

                sb.Append(line);
                sb.Append("\r\n");
            }

            content = sb.ToString();

            var questions = new List<Question>();

            //分解试题源文本，分解成试题列表。
            if (string.IsNullOrEmpty(content))
            {
                return null;
            }

            var outlineExamText = OutLineExamsText(content);
            var errorMsgOfOneFile = new StringBuilder();  // 一定要分两层错误消息
            if (QuestionValidateManager.ValidateForPresentation(outlineExamText, errorMsgOfOneFile) == false)
            {
                errorMsg.Append(errorMsgOfOneFile);
                return null;
            }
            int index = content.IndexOf("＜信息＞＞＞");
            if (index >= 0)
            {
                content = content.Substring(index + 6);
            }

            List<string> baseQuestionStrings = new List<String>();

            int previewIndex = -1;
            index = content.IndexOf("试题＞＞");

            while (index >= 0 && index < content.Length)
            {
                if (previewIndex > -1 && previewIndex <= index)
                {
                    String baseQuestionText = content.Substring(previewIndex, index - previewIndex);
                    baseQuestionStrings.Add(baseQuestionText);
                }

                previewIndex = index;
                index = content.IndexOf("试题＞＞", index + 4);
            }

            if (previewIndex >= 0 && index < 0)
            {
                // 最后一道题
                baseQuestionStrings.Add(content.Substring(previewIndex));
            }
            else
            {
                baseQuestionStrings.Add(content);
            }

            foreach (string baseQuestionString in baseQuestionStrings)
            {
                List<Question> newQuestions = BaseQuestion.BuildQuestionList(baseQuestionString, true);
                if (newQuestions != null)
                {
                    questions.AddRange(newQuestions);
                }
            }

            FormatQuestions(ref questions);

            return questions;
        }

        /// <summary>
        /// 根据指定编辑器中的文本分拆出试题对象集。
        /// </summary>
        /// <param name="editor">指定编辑器。</param>
        /// <param name="errorMsg">错误消息。</param>
        /// <returns>返回试题对象列表。</returns>
        public static List<Question> BuildQuestions(MarkdownEditor editor, StringBuilder errorMsg)
        {
            if (editor == null)
            {
                errorMsg.Append("未指定编辑器。");
                return null;
            }

            return BuildQuestions(editor.FullFilePath, errorMsg);
        }

        /// <summary>
        /// 对列表中的试题进行格式化。例如添加序号等。
        /// </summary>
        public static void FormatQuestions(ref List<Question> questions)
        {
            var regexChoiceAnswer = new Regex(@"(?<=【).{1,}(?=】)");

            for (int i = 0; i < questions.Count; i++)
            {
                var q = questions[i];
                q.OrderNumber = i + 1;
                switch (q.Type)
                {
                    case QuestionType.Choice:
                    case QuestionType.Judge:
                        {
                            var answer = "";
                            var mAnswer = regexChoiceAnswer.Match(q.TitleString);
                            if (mAnswer.Success)
                            {
                                answer = mAnswer.Value;
                            }

                            for (int j = 0; j < q.ChoiceItems.Count; j++)
                            {
                                var ci = q.ChoiceItems[j];
                                ci.OrderNumber = j + 1;
                                if (string.IsNullOrWhiteSpace(answer) == false && answer == ci.Text)
                                {
                                    ci.IsAnswer = true;
                                    q.AnswerNumMark = ConvertToAlphaNumber(ci.OrderNumber);
                                }
                            }

                            break;
                        }
                        // 为什么要去除呢？因为这样会导致填空题没有答案！！
                        // 这种转换应该交由调用的方法自己去完成。
                        //case QuestionType.FillBlank:
                        //    {
                        //        var title = q.TitleString.Trim(new char[] { '\r', '\n', });
                        //        var regFillBlank = new Regex(@"(?<=【).{1,}?(?=】)");
                        //        var matches = regFillBlank.Matches(title);
                        //        if (matches.Count > 0)
                        //        {
                        //            for (int j = matches.Count - 1; j >= 0; j--)
                        //            {
                        //                var m = matches[j];
                        //                if (m.Length > 0)
                        //                {
                        //                    title = title.Substring(0, m.Index) + ConvertToBlank(m.Value) + title.Substring(m.Index + m.Length);
                        //                }
                        //            }
                        //            q.TitleString = title;
                        //        }
                        //        break;
                        //    }
                }
            }
        }

        private static string ConvertToBlank(string value)
        {
            if (string.IsNullOrEmpty(value)) return "";

            var sb = new StringBuilder();
            foreach (char c in value)
            {
                if (Encoding.Default.GetByteCount(new char[] { c, }) >= 2)
                {
                    sb.Append('　');
                }
                else
                {
                    sb.Append(' ');
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 只支持 1~26。
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public static string ConvertToAlphaNumber(int i)
        {
            if (i >= 1 && i <= 26)
            {
                return ((char)((int)'A' + i - 1)).ToString();
            }

            return i.ToString();
        }

        /// <summary>
        /// 为向 Word 插入图像，进行尺寸转换。
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public static void ConvertImageSize(ref double width, ref double height)
        {
            var hc = height * 2.54 / 72;
            var wc = width * 2.54 / 72;
            if (wc > 14)
            {
                var hr = (hc / (wc / 14)) * 360000;
                var wr = 14 * 360000;
                width = wr;
                height = hr;
            }
            else
            {
                width = wc * 360000;
                height = hc * 360000;
            }
        }

        /// <summary>
        /// 根据指定的文件名，提取出其中所有试题。
        /// </summary>
        /// <param name="filePathes">文件路径列表。</param>
        /// <returns></returns>
        public static List<QuestionList> GetQuestionListsFromFiles(List<string> filePathes)
        {
            try
            {
                if (filePathes == null || filePathes.Count <= 0) return null;

                var qlList = new List<QuestionList>();
                var errorMsg = new StringBuilder();
                foreach (var filePath in filePathes)
                {
                    if (System.IO.File.Exists(filePath) == false) continue;

                    var ql = new QuestionList() { FilePath = filePath, };
                    var questions = BuildQuestions(filePath, errorMsg);
                    if (questions != null && questions.Count > 0)
                    {
                        ql.AddRange(questions);
                        qlList.Add(ql);
                    }
                }

                return qlList;
            }
            catch (Exception ex)
            {
                LMessageBox.Show(ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 从指定的文件中提取试题。
        /// </summary>
        /// <param name="mdFileList">指定的 Markdown 文件列表。</param>
        /// <param name="ignoreFilePath">要忽略的，通常应传入活动文档。因为从活动文档中提取试题到活动文档没什么意义。</param>
        /// <returns>返回列表的列表。每个子列表对应一个 Markdown 文件，其中包括从这个 Markdown 文件中提取的所有试题。</returns>
        public static List<QuestionList> GetQuestionListFromMarkdownFiles(List<MarkdownFile> mdFileList, string ignoreFilePath = null)
        {
            try
            {
                if (mdFileList == null || mdFileList.Count <= 0) return null;

                var qlList = new List<QuestionList>();
                var errorMsg = new StringBuilder();
                foreach (var mdFile in mdFileList)
                {
                    if (string.IsNullOrWhiteSpace(ignoreFilePath) == false
                        && mdFile.FullPath.ToLower() == ignoreFilePath.ToLower()) continue;

                    if (System.IO.File.Exists(mdFile.FullPath) == false) continue;

                    var ql = new QuestionList() { FilePath = mdFile.FullPath, };
                    var questions = BuildQuestions(mdFile.FullPath, errorMsg);
                    if (questions != null && questions.Count > 0)
                    {
                        ql.AddRange(questions);
                        qlList.Add(ql);
                    }
                }

                return qlList;
            }
            catch (Exception ex)
            {
                LMessageBox.Show(ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 将当前 Markdown 文档中的试题导出为 Word 文档。
        /// </summary>
        /// <param name="editor"></param>
        public static void ExportToWordDocument(MarkdownEditor editor = null, bool withGroupAnswer = false)
        {
            if (editor == null)
            {
                editor = Globals.MainWindow.ActivedEditor;
            }

            if (editor == null)
            {
                LMessageBox.ShowWarning("未指定要提取试题的编辑器！");
                return;
            }

            if (editor.IsModified)
            {
                LMessageBox.ShowInfomation("这个功能是以磁盘内容而不是当前编辑器的内容为基准的。\r\n\r\n　　请先保存文件。");
                return;
            }

            //if (editor.EditorBase.Text.Contains("｜") || editor.EditorBase.Text.Contains("|"))
            //{
            //    var answer = LMessageBox.Show("发现源文件中带有 ｜ 或 | 字符。这两个字符在 LME 中通常用以定义二维文字表。\r\n\r\n　　本功能目前在导出试题时尚不支持二维文字表。\r\n\r\n　　要继续吗？",
            //         Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
            //    if (answer != MessageBoxResult.Yes) return;
            //}

            var errorMsg = new StringBuilder();
            var questions = BuildQuestions(editor, errorMsg);
            if (questions == null || questions.Count <= 0)
            {
                LMessageBox.ShowWarning("未指定编辑器或编辑器中无试题文本！");
                return;
            }

            var qcount = 0;
            foreach (var q in questions)
            {
                if (q.Type != QuestionType.Text)
                    qcount++;
            }

            if (qcount <= 0)
            {
                LMessageBox.ShowWarning("没能在当前演示界面中找到试题，无法执行。");
                return;
            }

            var testpaper_title = "";
            var regTitle = new Regex(@"^%.*$", RegexOptions.Multiline);
            var matchTitle = regTitle.Match(editor.EditorBase.Text);
            if (matchTitle.Success)
            {
                testpaper_title = matchTitle.Value.Trim(new char[] { '%', ' ', '　', '\t', '\r', '\t', }).Replace("\r", "").Replace("\n", "");
            }

            if (string.IsNullOrWhiteSpace(testpaper_title))
                testpaper_title = "新试卷";

            SaveFileDialog sfd = new SaveFileDialog() { Title = Globals.AppName, };
            sfd.Filter = "Word 文档(*.docx)|*.docx";
            sfd.FilterIndex = 0;
            sfd.FileName = testpaper_title;

            sfd.InitialDirectory = Globals.PathOfDeskTop;

            if (sfd.ShowDialog() != true) return;

            // 下面生成 Word 文档
            try
            {
                var m_Docx = new XWPFDocument();
                var doc = m_Docx.Document;
                var body = doc.body;
                body.sectPr = new CT_SectPr();
                var m_SectPr = body.sectPr;
                var columns = m_SectPr.cols;
                columns.num = "2";
                columns.space = 2 * 567;

                // 设置 Word 文档的页面尺寸（页面设置）
                // m_SectPr.pgSz.h = 16838;        // A4 ,twip,缇
                // m_SectPr.pgSz.w = 11906;        // A4 ,twip,缇
                // m_SectPr.pgMar.left = 1587;     // 左边距,2.8cm
                // m_SectPr.pgMar.right = 1474;    // 右边距,2.6cm
                // m_SectPr.pgMar.top = "2097";    // 上边距,3.7cm
                // m_SectPr.pgMar.bottom = "1984"; // 下边距,3.5cm

                // 1缇等于1/1440英寸或1/567厘米。
                m_SectPr.pgSz.h = (ulong)(25.7 * 567);        // B4 ,twip,缇
                m_SectPr.pgSz.w = (ulong)(36.4 * 567);        // B4 ,twip,缇
                m_SectPr.pgMar.left = 2 * 567;                // 左边距,2.8cm
                m_SectPr.pgMar.right = 2 * 567;               // 右边距,2.6cm
                m_SectPr.pgMar.top = (2 * 567).ToString();    // 上边距,3.7cm
                m_SectPr.pgMar.bottom = (2 * 567).ToString(); // 下边距,3.5cm

                #region 输出试卷
                var titlePara = m_Docx.CreateParagraph();
                titlePara.Alignment = ParagraphAlignment.CENTER;
                var titleRun = titlePara.CreateRun();
                titleRun.SetText(testpaper_title);
                titleRun.FontFamily = "宋体";
                titleRun.FontSize = 16;  // 三号字
                titleRun.IsBold = true;

                var trimChars = new char[] { '\r', '\n', ' ', '　', '\t', };

                var choiceAnswersText = new StringBuilder();

                // 输出试题
                var indent = NopiHelper.Indentation("宋体", 21, 2, System.Drawing.FontStyle.Regular);
                string choiceGroupAnswer = "";
                foreach (var q in questions)
                {
                    switch (q.Type)
                    {
                        case QuestionType.Judge:
                            {
                                if (withGroupAnswer && choiceGroupAnswer.Length > 0)
                                {
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();  // 加十个空行才够用
                                    var tpcga = m_Docx.CreateParagraph();
                                    var trncga = tpcga.CreateRun();
                                    trncga.SetText("本组答案：" + choiceGroupAnswer);
                                    trncga.FontFamily = "楷体";
                                    trncga.FontSize = 11;   // 比五号字略大
                                    trncga.IsBold = true;
                                    trncga.SetColor("ff0000");
                                }

                                var tp = m_Docx.CreateParagraph();
                                var trn = tp.CreateRun();
                                trn.SetText(q.OrderNumber + "．[判断题] ");
                                trn.FontFamily = "楷体";
                                trn.FontSize = 11;   // 比五号字略大
                                trn.IsBold = true;

                                var baseTitle = q.TitleString.Replace("\r", "");
                                var indexOfLineBreak = baseTitle.IndexOf("\n");

                                if (indexOfLineBreak < 0 || (q.TitleString.Contains("｜") == false && q.TitleString.Contains("|") == false))
                                {
                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"(?<=【).{1,}?(?=】)", q.TitleString.Trim(trimChars));
                                    foreach (var piece in pieces)
                                    {
                                        var tr = tp.CreateRun();
                                        if (piece.IsMartchText)
                                        {
                                            tr.SetText("  ");
                                        }
                                        else
                                        {
                                            tr.SetText(piece.SourceText.Replace("\\_", "_"));
                                        }
                                        tr.FontFamily = "楷体";
                                        tr.FontSize = 11;
                                        tr.IsBold = true;
                                    }
                                }
                                else
                                {
                                    var fstLine = baseTitle.Substring(0, indexOfLineBreak);

                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"(?<=【).{1,}?(?=】)", fstLine.Trim(trimChars));
                                    foreach (var piece in pieces)
                                    {
                                        var tr = tp.CreateRun();
                                        if (piece.IsMartchText)
                                        {
                                            tr.SetText("  ");
                                        }
                                        else
                                        {
                                            tr.SetText(piece.SourceText.Replace("\\_", "_"));
                                        }
                                        tr.FontFamily = "楷体";
                                        tr.FontSize = 11;
                                        tr.IsBold = true;
                                    }

                                    var lines = baseTitle.Substring(indexOfLineBreak).Split(new char[] { '\n', }, StringSplitOptions.None);
                                    var md = new MarkdownSharp.Markdown();
                                    var tableInfos = CustomMarkdownSupport.CompileTextTable(lines, ref md);

                                    for (int tIndex = 0; tIndex < tableInfos.Count; tIndex++)
                                    {
                                        var ti = tableInfos[tIndex];
                                        if (ti.TableLines.Count <= 0 || ti.ColumnAlignments.Count <= 0) continue;

                                        XWPFTable tableContent = m_Docx.CreateTable(ti.TableLines.Count - ti.ColumnDefinitionLinesCount, ti.ColumnAlignments.Count);
                                        var tableArray = m_Docx.Document.body.GetTblArray();
                                        CT_Tbl m_CTTbl = tableArray[tableArray.Length - 1];  //获得文档中最新的表

                                        m_CTTbl.AddNewTblPr().jc = new CT_Jc();
                                        m_CTTbl.AddNewTblPr().jc.val = ST_Jc.center;//表在页面水平居中

                                        TableLine preTableLine = null;
                                        for (int li = 0; li < ti.TableLines.Count; li++)
                                        {
                                            var tl = ti.TableLines[li];
                                            if (preTableLine == null)
                                            {
                                                preTableLine = tl;
                                            }
                                            else
                                            {
                                                if (tl.Type == TableLineType.MergeLine)
                                                {
                                                    for (int ci = 0; ci < Math.Min(preTableLine.Cells.Count, tl.Cells.Count); ci++)
                                                    {
                                                        preTableLine.Cells[ci] += tl.Cells[ci];
                                                    }
                                                }
                                                else if (tl.Type == TableLineType.Normal)
                                                {
                                                    preTableLine = tl;
                                                }
                                            }  // 不考虑列定义行，统一居中。  
                                        }

                                        var cdLinesCount = 0;
                                        for (int li = 0; li < ti.TableLines.Count; li++)
                                        {
                                            var tl = ti.TableLines[li];
                                            if (tl.HeaderOrBodyType == HeaderOrBodyType.ColumnDifinition)
                                            {
                                                cdLinesCount++;
                                                continue;
                                            }

                                            if (tl.Type == TableLineType.Normal)  // 合并的行已经合并上去了，可以直接忽略了。
                                            {
                                                var row = tableContent.GetRow(li - cdLinesCount);
                                                for (int ci = 0; ci < tl.Cells.Count; ci++)
                                                {
                                                    row.GetCell(ci).SetParagraph(SetCellText(m_Docx, tableContent, tl.Cells[ci], tl.HeaderOrBodyType == HeaderOrBodyType.HeaderLine));
                                                }
                                            }
                                        }
                                    }
                                }

                                var imagePath = editor.GetRealPathFromRelativeImagePath(q.MarkdownImagePath);
                                if (System.IO.File.Exists(imagePath))
                                {
                                    double width, height;
                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var img = Image.FromStream(gfs1);
                                        width = img.Width;
                                        height = img.Height;
                                        ConvertImageSize(ref width, ref height);
                                    }

                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var c_p = m_Docx.Document.body.AddNewP();
                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                        var cp = new XWPFParagraph(c_p, m_Docx);
                                        var cr = cp.CreateRun();
                                        cr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                        cp.IndentationFirstLine = 0;
                                    }
                                }

                                // 判断题不输出选项。

                                choiceAnswersText.Append($"{q.OrderNumber}．{(q.Answer == "正确" ? "√" : "×")}");
                                if (q.OrderNumber % 5 == 0)
                                {
                                    choiceAnswersText.Append("\r\n");
                                }
                                else
                                {
                                    choiceAnswersText.Append("\t");
                                }
                                break;
                            }
                        case QuestionType.Choice:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var trn = tp.CreateRun();
                                trn.SetText(q.OrderNumber + "．");
                                trn.FontFamily = "楷体";
                                trn.FontSize = 11;   // 比五号字略大
                                trn.IsBold = true;

                                var baseTitle = q.TitleString.Replace("\r", "");
                                var indexOfLineBreak = baseTitle.IndexOf("\n");

                                if (indexOfLineBreak < 0 || (q.TitleString.Contains("｜") == false && q.TitleString.Contains("|") == false))
                                {
                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"(?<=【).{1,}?(?=】)", q.TitleString.Trim(trimChars));
                                    foreach (var piece in pieces)
                                    {
                                        var tr = tp.CreateRun();
                                        if (piece.IsMartchText)
                                        {
                                            tr.SetText("  ");
                                        }
                                        else
                                        {
                                            tr.SetText(piece.SourceText.Replace("\\_", "_"));
                                        }
                                        tr.FontFamily = "楷体";
                                        tr.FontSize = 11;
                                        tr.IsBold = true;
                                    }
                                }
                                else
                                {
                                    var fstLine = baseTitle.Substring(0, indexOfLineBreak);

                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"(?<=【).{1,}?(?=】)", fstLine.Trim(trimChars));
                                    foreach (var piece in pieces)
                                    {
                                        var tr = tp.CreateRun();
                                        if (piece.IsMartchText)
                                        {
                                            tr.SetText("  ");
                                        }
                                        else
                                        {
                                            tr.SetText(piece.SourceText.Replace("\\_", "_"));
                                        }
                                        tr.FontFamily = "楷体";
                                        tr.FontSize = 11;
                                        tr.IsBold = true;
                                    }

                                    var lines = baseTitle.Substring(indexOfLineBreak).Split(new char[] { '\n', }, StringSplitOptions.None);
                                    var md = new MarkdownSharp.Markdown();
                                    var tableInfos = CustomMarkdownSupport.CompileTextTable(lines, ref md);

                                    for (int tIndex = 0; tIndex < tableInfos.Count; tIndex++)
                                    {
                                        var ti = tableInfos[tIndex];
                                        if (ti.TableLines.Count <= 0 || ti.ColumnAlignments.Count <= 0) continue;

                                        XWPFTable tableContent = m_Docx.CreateTable(ti.TableLines.Count - ti.ColumnDefinitionLinesCount, ti.ColumnAlignments.Count);
                                        var tableArray = m_Docx.Document.body.GetTblArray();
                                        CT_Tbl m_CTTbl = tableArray[tableArray.Length - 1];  //获得文档中最新的表

                                        m_CTTbl.AddNewTblPr().jc = new CT_Jc();
                                        m_CTTbl.AddNewTblPr().jc.val = ST_Jc.center;//表在页面水平居中

                                        TableLine preTableLine = null;
                                        for (int li = 0; li < ti.TableLines.Count; li++)
                                        {
                                            var tl = ti.TableLines[li];
                                            if (preTableLine == null)
                                            {
                                                preTableLine = tl;
                                            }
                                            else
                                            {
                                                if (tl.Type == TableLineType.MergeLine)
                                                {
                                                    for (int ci = 0; ci < Math.Min(preTableLine.Cells.Count, tl.Cells.Count); ci++)
                                                    {
                                                        preTableLine.Cells[ci] += tl.Cells[ci];
                                                    }
                                                }
                                                else if (tl.Type == TableLineType.Normal)
                                                {
                                                    preTableLine = tl;
                                                }
                                            }  // 不考虑列定义行，统一居中。  
                                        }

                                        var cdLinesCount = 0;
                                        for (int li = 0; li < ti.TableLines.Count; li++)
                                        {
                                            var tl = ti.TableLines[li];
                                            if (tl.HeaderOrBodyType == HeaderOrBodyType.ColumnDifinition)
                                            {
                                                cdLinesCount++;
                                                continue;
                                            }

                                            if (tl.Type == TableLineType.Normal)  // 合并的行已经合并上去了，可以直接忽略了。
                                            {
                                                var row = tableContent.GetRow(li - cdLinesCount);
                                                for (int ci = 0; ci < tl.Cells.Count; ci++)
                                                {
                                                    row.GetCell(ci).SetParagraph(SetCellText(m_Docx, tableContent, tl.Cells[ci], tl.HeaderOrBodyType == HeaderOrBodyType.HeaderLine));
                                                }
                                            }
                                        }
                                    }
                                }

                                var imagePath = editor.GetRealPathFromRelativeImagePath(q.MarkdownImagePath);
                                if (System.IO.File.Exists(imagePath))
                                {
                                    double width, height;
                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var img = Image.FromStream(gfs1);
                                        width = img.Width;
                                        height = img.Height;
                                        ConvertImageSize(ref width, ref height);
                                    }

                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var c_p = m_Docx.Document.body.AddNewP();
                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                        var cp = new XWPFParagraph(c_p, m_Docx);
                                        var cr = cp.CreateRun();
                                        cr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                        cp.IndentationFirstLine = 0;
                                    }
                                }

                                // 写选项。
                                if (q.ChoiceItems.Count != 4)
                                {
                                    foreach (var ci in q.ChoiceItems)
                                    {
                                        var bp = m_Docx.CreateParagraph();
                                        bp.IndentationFirstLine = indent;
                                        var brn = bp.CreateRun();
                                        brn.SetText(ConvertToAlphaNumber(ci.OrderNumber) + "．");
                                        brn.FontFamily = "宋体";
                                        brn.FontSize = 11;
                                        var br = bp.CreateRun();
                                        br.SetText(ci.Text.Replace("\r\n", ""));
                                        br.FontFamily = "宋体";
                                        br.FontSize = 11;
                                    }
                                }
                                else
                                {
                                    // 针对四个选项的情况，进行特别优化布局
                                    q.ChoiceItems[0].Text = q.ChoiceItems[0].Text.Trim(trimChars);
                                    q.ChoiceItems[1].Text = q.ChoiceItems[1].Text.Trim(trimChars);
                                    q.ChoiceItems[2].Text = q.ChoiceItems[2].Text.Trim(trimChars);
                                    q.ChoiceItems[3].Text = q.ChoiceItems[3].Text.Trim(trimChars);

                                    var lenA = GetTextWidth(q.ChoiceItems[0].Text);
                                    var lenB = GetTextWidth(q.ChoiceItems[1].Text);
                                    var lenC = GetTextWidth(q.ChoiceItems[2].Text);
                                    var lenD = GetTextWidth(q.ChoiceItems[3].Text);

                                    if (lenA <= 14 && lenB <= 14 && lenC <= 14 && lenD <= 14)  //四个选项都不超过7个全角字符
                                    {
                                        // ABCD
                                        var bpABCD = m_Docx.CreateParagraph();
                                        bpABCD.IndentationFirstLine = indent;
                                        // a
                                        var brnA = bpABCD.CreateRun();
                                        brnA.SetText(ConvertToAlphaNumber(q.ChoiceItems[0].OrderNumber) + "．");
                                        brnA.FontFamily = "宋体";
                                        brnA.FontSize = 11;
                                        var brA = bpABCD.CreateRun();
                                        brA.SetText(AppendBlanks(q.ChoiceItems[0].Text, "《“".Contains(q.ChoiceItems[0].Text[0]) ? 15 : 14));
                                        // ．《 在一起时，会自动压缩字符间距，因为没找到对应选项取消标点间距自动压缩，只得用这个办法。
                                        brA.FontFamily = "宋体";
                                        brA.FontSize = 11;
                                        // b
                                        var brnB = bpABCD.CreateRun();
                                        brnB.SetText(ConvertToAlphaNumber(q.ChoiceItems[1].OrderNumber) + "．");
                                        brnB.FontFamily = "宋体";
                                        brnB.FontSize = 11;
                                        var brB = bpABCD.CreateRun();
                                        brB.SetText(AppendBlanks(q.ChoiceItems[1].Text, "《“".Contains(q.ChoiceItems[1].Text[0]) ? 15 : 14));
                                        // ．《 在一起时，会自动压缩字符间距，因为没找到对应选项取消标点间距自动压缩，只得用这个办法。
                                        brB.FontFamily = "宋体";
                                        brB.FontSize = 11;
                                        // c
                                        var brnC = bpABCD.CreateRun();
                                        brnC.SetText(ConvertToAlphaNumber(q.ChoiceItems[2].OrderNumber) + "．");
                                        brnC.FontFamily = "宋体";
                                        brnC.FontSize = 11;
                                        var brC = bpABCD.CreateRun();
                                        brC.SetText(AppendBlanks(q.ChoiceItems[2].Text, "《“".Contains(q.ChoiceItems[2].Text[0]) ? 15 : 14));
                                        // ．《 在一起时，会自动压缩字符间距，因为没找到对应选项取消标点间距自动压缩，只得用这个办法。
                                        brC.FontFamily = "宋体";
                                        brC.FontSize = 11;
                                        // d
                                        var brnD = bpABCD.CreateRun();
                                        brnD.SetText(ConvertToAlphaNumber(q.ChoiceItems[3].OrderNumber) + "．");
                                        brnD.FontFamily = "宋体";
                                        brnD.FontSize = 11;
                                        var brD = bpABCD.CreateRun();
                                        brD.SetText(q.ChoiceItems[3].Text);  // 这个不追加空格
                                        brD.FontFamily = "宋体";
                                        brD.FontSize = 11;
                                    }
                                    else if (lenA <= 31 && lenB <= 31)
                                    {
                                        if (lenC <= 31 && lenD <= 31)
                                        {
                                            // AB
                                            // CD
                                            var bpAB = m_Docx.CreateParagraph();
                                            bpAB.IndentationFirstLine = indent;
                                            // a
                                            var brnA = bpAB.CreateRun();
                                            brnA.SetText(ConvertToAlphaNumber(q.ChoiceItems[0].OrderNumber) + "．");
                                            brnA.FontFamily = "宋体";
                                            brnA.FontSize = 11;
                                            var brA = bpAB.CreateRun();
                                            brA.SetText(AppendBlanks(q.ChoiceItems[0].Text, 31));
                                            brA.FontFamily = "宋体";
                                            brA.FontSize = 11;
                                            // b
                                            var brnB = bpAB.CreateRun();
                                            brnB.SetText(ConvertToAlphaNumber(q.ChoiceItems[1].OrderNumber) + "．");
                                            brnB.FontFamily = "宋体";
                                            brnB.FontSize = 11;
                                            var brB = bpAB.CreateRun();
                                            brB.SetText(q.ChoiceItems[1].Text);  // 不追加空格
                                            brB.FontFamily = "宋体";
                                            brB.FontSize = 11;
                                            // CD
                                            var bpCD = m_Docx.CreateParagraph();
                                            bpCD.IndentationFirstLine = indent;
                                            // c
                                            var brnC = bpCD.CreateRun();
                                            brnC.SetText(ConvertToAlphaNumber(q.ChoiceItems[2].OrderNumber) + "．");
                                            brnC.FontFamily = "宋体";
                                            brnC.FontSize = 11;
                                            var brC = bpCD.CreateRun();
                                            brC.SetText(AppendBlanks(q.ChoiceItems[2].Text, 31));
                                            brC.FontFamily = "宋体";
                                            brC.FontSize = 11;
                                            // d
                                            var brnD = bpCD.CreateRun();
                                            brnD.SetText(ConvertToAlphaNumber(q.ChoiceItems[3].OrderNumber) + "．");
                                            brnD.FontFamily = "宋体";
                                            brnD.FontSize = 11;
                                            var brD = bpCD.CreateRun();
                                            brD.SetText(q.ChoiceItems[3].Text);  // 不追加空格
                                            brD.FontFamily = "宋体";
                                            brD.FontSize = 11;
                                        }
                                        else
                                        {
                                            // AB
                                            // C
                                            // D
                                            var bpAB = m_Docx.CreateParagraph();
                                            bpAB.IndentationFirstLine = indent;
                                            // a
                                            var brnA = bpAB.CreateRun();
                                            brnA.SetText(ConvertToAlphaNumber(q.ChoiceItems[0].OrderNumber) + "．");
                                            brnA.FontFamily = "宋体";
                                            brnA.FontSize = 11;
                                            var brA = bpAB.CreateRun();
                                            brA.SetText(AppendBlanks(q.ChoiceItems[0].Text, 31));
                                            brA.FontFamily = "宋体";
                                            brA.FontSize = 11;
                                            // b
                                            var brnB = bpAB.CreateRun();
                                            brnB.SetText(ConvertToAlphaNumber(q.ChoiceItems[1].OrderNumber) + "．");
                                            brnB.FontFamily = "宋体";
                                            brnB.FontSize = 11;
                                            var brB = bpAB.CreateRun();
                                            brB.SetText(q.ChoiceItems[1].Text);    // 不追加空格
                                            brB.FontFamily = "宋体";
                                            brB.FontSize = 11;
                                            // C
                                            var bpC = m_Docx.CreateParagraph();
                                            bpC.IndentationFirstLine = indent;
                                            // c
                                            var brnC = bpC.CreateRun();
                                            brnC.SetText(ConvertToAlphaNumber(q.ChoiceItems[2].OrderNumber) + "．");
                                            brnC.FontFamily = "宋体";
                                            brnC.FontSize = 11;
                                            var brC = bpC.CreateRun();
                                            brC.SetText(q.ChoiceItems[2].Text);
                                            brC.FontFamily = "宋体";
                                            brC.FontSize = 11;
                                            // D
                                            var bpD = m_Docx.CreateParagraph();
                                            bpD.IndentationFirstLine = indent;
                                            // d
                                            var brnD = bpD.CreateRun();
                                            brnD.SetText(ConvertToAlphaNumber(q.ChoiceItems[3].OrderNumber) + "．");
                                            brnD.FontFamily = "宋体";
                                            brnD.FontSize = 11;
                                            var brD = bpD.CreateRun();
                                            brD.SetText(q.ChoiceItems[3].Text);
                                            brD.FontFamily = "宋体";
                                            brD.FontSize = 11;
                                        }
                                    }
                                    else
                                    {
                                        if (lenB <= 31 && lenC <= 31)
                                        {
                                            // A
                                            // BC
                                            // D
                                            var bpA = m_Docx.CreateParagraph();
                                            bpA.Alignment = ParagraphAlignment.LEFT;
                                            bpA.IndentationFirstLine = indent;
                                            // a
                                            var brnA = bpA.CreateRun();
                                            brnA.SetText(ConvertToAlphaNumber(q.ChoiceItems[0].OrderNumber) + "．");
                                            brnA.FontFamily = "宋体";
                                            brnA.FontSize = 11;
                                            var brA = bpA.CreateRun();
                                            brA.SetText(q.ChoiceItems[0].Text);
                                            brA.FontFamily = "宋体";
                                            brA.FontSize = 11;
                                            // BC
                                            var bpBC = m_Docx.CreateParagraph();
                                            bpBC.IndentationFirstLine = indent;
                                            bpBC.Alignment = ParagraphAlignment.LEFT;
                                            // b
                                            var brnB = bpBC.CreateRun();
                                            brnB.SetText(ConvertToAlphaNumber(q.ChoiceItems[1].OrderNumber) + "．");
                                            brnB.FontFamily = "宋体";
                                            brnB.FontSize = 11;
                                            var brB = bpBC.CreateRun();
                                            brB.SetText(AppendBlanks(q.ChoiceItems[1].Text, 31));
                                            brB.FontFamily = "宋体";
                                            brB.FontSize = 11;
                                            // c
                                            var brnC = bpBC.CreateRun();
                                            brnC.SetText(ConvertToAlphaNumber(q.ChoiceItems[2].OrderNumber) + "．");
                                            brnC.FontFamily = "宋体";
                                            brnC.FontSize = 11;
                                            var brC = bpBC.CreateRun();
                                            brC.SetText(q.ChoiceItems[2].Text);  // 不追加空格
                                            brC.FontFamily = "宋体";
                                            brC.FontSize = 11;
                                            // D
                                            var bpD = m_Docx.CreateParagraph();
                                            bpD.IndentationFirstLine = indent;
                                            bpD.Alignment = ParagraphAlignment.LEFT;
                                            // d
                                            var brnD = bpD.CreateRun();
                                            brnD.SetText(ConvertToAlphaNumber(q.ChoiceItems[3].OrderNumber) + "．");
                                            brnD.FontFamily = "宋体";
                                            brnD.FontSize = 11;
                                            var brD = bpD.CreateRun();
                                            brD.SetText(q.ChoiceItems[3].Text);
                                            brD.FontFamily = "宋体";
                                            brD.FontSize = 11;
                                        }
                                        else
                                        {
                                            if (lenC <= 31 && lenD <= 31)
                                            {
                                                // A
                                                // B
                                                // CD
                                                var bpA = m_Docx.CreateParagraph();
                                                bpA.IndentationFirstLine = indent;
                                                bpA.Alignment = ParagraphAlignment.LEFT;
                                                // a
                                                var brnA = bpA.CreateRun();
                                                brnA.SetText(ConvertToAlphaNumber(q.ChoiceItems[0].OrderNumber) + "．");
                                                brnA.FontFamily = "宋体";
                                                brnA.FontSize = 11;
                                                var brA = bpA.CreateRun();
                                                brA.SetText(q.ChoiceItems[0].Text);
                                                brA.FontFamily = "宋体";
                                                brA.FontSize = 11;
                                                // B
                                                var bpB = m_Docx.CreateParagraph();
                                                bpB.IndentationFirstLine = indent;
                                                bpB.Alignment = ParagraphAlignment.LEFT;
                                                // b
                                                var brnB = bpB.CreateRun();
                                                brnB.SetText(ConvertToAlphaNumber(q.ChoiceItems[1].OrderNumber) + "．");
                                                brnB.FontFamily = "宋体";
                                                brnB.FontSize = 11;
                                                var brB = bpB.CreateRun();
                                                brB.SetText(q.ChoiceItems[1].Text);
                                                brB.FontFamily = "宋体";
                                                brB.FontSize = 11;
                                                // C
                                                var bpCD = m_Docx.CreateParagraph();
                                                bpCD.IndentationFirstLine = indent;
                                                bpCD.Alignment = ParagraphAlignment.LEFT;
                                                // c
                                                var brnC = bpCD.CreateRun();
                                                brnC.SetText(ConvertToAlphaNumber(q.ChoiceItems[2].OrderNumber) + "．");
                                                brnC.FontFamily = "宋体";
                                                brnC.FontSize = 11;
                                                var brC = bpCD.CreateRun();
                                                brC.SetText(AppendBlanks(q.ChoiceItems[2].Text, 31));
                                                brC.FontFamily = "宋体";
                                                brC.FontSize = 11;
                                                // d
                                                var brnD = bpCD.CreateRun();
                                                brnD.SetText(ConvertToAlphaNumber(q.ChoiceItems[3].OrderNumber) + "．");
                                                brnD.FontFamily = "宋体";
                                                brnD.FontSize = 11;
                                                var brD = bpCD.CreateRun();
                                                brD.SetText(q.ChoiceItems[3].Text);    // 不追加空格
                                                brD.FontFamily = "宋体";
                                                brD.FontSize = 11;
                                            }
                                            else
                                            {
                                                // A
                                                // B
                                                // C
                                                // D
                                                var bpA = m_Docx.CreateParagraph();
                                                bpA.IndentationFirstLine = indent;
                                                bpA.Alignment = ParagraphAlignment.LEFT;
                                                // a
                                                var brnA = bpA.CreateRun();
                                                brnA.SetText(ConvertToAlphaNumber(q.ChoiceItems[0].OrderNumber) + "．");
                                                brnA.FontFamily = "宋体";
                                                brnA.FontSize = 11;
                                                var brA = bpA.CreateRun();
                                                brA.SetText(q.ChoiceItems[0].Text);
                                                brA.FontFamily = "宋体";
                                                brA.FontSize = 11;
                                                // B
                                                var bpB = m_Docx.CreateParagraph();
                                                bpB.IndentationFirstLine = indent;
                                                bpB.Alignment = ParagraphAlignment.LEFT;
                                                // b
                                                var brnB = bpB.CreateRun();
                                                brnB.SetText(ConvertToAlphaNumber(q.ChoiceItems[1].OrderNumber) + "．");
                                                brnB.FontFamily = "宋体";
                                                brnB.FontSize = 11;
                                                var brB = bpB.CreateRun();
                                                brB.SetText(q.ChoiceItems[1].Text);
                                                brB.FontFamily = "宋体";
                                                brB.FontSize = 11;
                                                // C
                                                var bpC = m_Docx.CreateParagraph();
                                                bpC.IndentationFirstLine = indent;
                                                bpC.Alignment = ParagraphAlignment.LEFT;
                                                // c
                                                var brnC = bpC.CreateRun();
                                                brnC.SetText(ConvertToAlphaNumber(q.ChoiceItems[2].OrderNumber) + "．");
                                                brnC.FontFamily = "宋体";
                                                brnC.FontSize = 11;
                                                var brC = bpC.CreateRun();
                                                brC.SetText(q.ChoiceItems[2].Text);
                                                brC.FontFamily = "宋体";
                                                brC.FontSize = 11;
                                                // D
                                                var bpD = m_Docx.CreateParagraph();
                                                bpD.IndentationFirstLine = indent;
                                                bpD.Alignment = ParagraphAlignment.LEFT;
                                                // d
                                                var brnD = bpD.CreateRun();
                                                brnD.SetText(ConvertToAlphaNumber(q.ChoiceItems[3].OrderNumber) + "．");
                                                brnD.FontFamily = "宋体";
                                                brnD.FontSize = 11;
                                                var brD = bpD.CreateRun();
                                                brD.SetText(q.ChoiceItems[3].Text);
                                                brD.FontFamily = "宋体";
                                                brD.FontSize = 11;
                                            }
                                        }
                                    }
                                }

                                // 记录答案标记字母，准备输出答案
                                choiceAnswersText.Append($"{q.OrderNumber}．{q.AnswerNumMark}");
                                choiceGroupAnswer += $"\t{q.OrderNumber}．{q.AnswerNumMark}";
                                if (q.OrderNumber % 5 == 0)
                                {
                                    choiceAnswersText.Append("\r\n");

                                    if (withGroupAnswer)
                                    {
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();
                                        m_Docx.CreateParagraph();  // 加十个空行才够用
                                        var tpcga = m_Docx.CreateParagraph();
                                        var trncga = tpcga.CreateRun();
                                        trncga.SetText("本组答案：" + choiceGroupAnswer);
                                        trncga.FontFamily = "楷体";
                                        trncga.FontSize = 11;   // 比五号字略大
                                        trncga.IsBold = true;
                                        trncga.SetColor("ff0000");

                                        choiceGroupAnswer = "";
                                    }
                                }
                                else
                                {
                                    choiceAnswersText.Append("\t");
                                }
                                break;
                            }
                        case QuestionType.FillBlank:
                            {
                                if (withGroupAnswer && choiceGroupAnswer.Length > 0)
                                {
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();  // 加十个空行才够用
                                    var tpcga = m_Docx.CreateParagraph();
                                    var trncga = tpcga.CreateRun();
                                    trncga.SetText("本组答案：" + choiceGroupAnswer);
                                    trncga.FontFamily = "楷体";
                                    trncga.FontSize = 11;   // 比五号字略大
                                    trncga.IsBold = true;
                                    trncga.SetColor("ff0000");
                                }

                                var tp = m_Docx.CreateParagraph();
                                var trn = tp.CreateRun();
                                trn.SetText(q.OrderNumber + "．");
                                trn.FontFamily = "楷体";
                                trn.FontSize = 11;   // 比五号字略大
                                trn.IsBold = true;

                                var pieces = Utils.Text.SplitToPiecesByRegex(@"【.{1,}?】", q.TitleString.Trim(trimChars));
                                foreach (var piece in pieces)
                                {
                                    var tfr = tp.CreateRun();
                                    if (piece.IsMartchText)
                                    {
                                        tfr.SetText(ConvertToBlank(piece.SourceText));
                                        tfr.SetUnderline(UnderlinePatterns.Single);
                                    }
                                    else
                                    {
                                        tfr.SetText(piece.SourceText);
                                    }
                                    tfr.FontFamily = "楷体";
                                    tfr.FontSize = 11;
                                    tfr.IsBold = true;
                                }

                                var imagePath = editor.GetRealPathFromRelativeImagePath(q.MarkdownImagePath);
                                if (System.IO.File.Exists(imagePath))
                                {
                                    double width, height;
                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var img = Image.FromStream(gfs1);
                                        width = img.Width;
                                        height = img.Height;
                                        ConvertImageSize(ref width, ref height);
                                    }

                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var c_p = m_Docx.Document.body.AddNewP();
                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                        var cp = new XWPFParagraph(c_p, m_Docx);
                                        var cr = cp.CreateRun();
                                        cr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                        cp.IndentationFirstLine = 0;
                                    }
                                }

                                break;
                            }
                        case QuestionType.Subjective:
                            {
                                if (withGroupAnswer && choiceGroupAnswer.Length > 0)
                                {
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();  // 加十个空行才够用
                                    var tpcga = m_Docx.CreateParagraph();
                                    var trncga = tpcga.CreateRun();
                                    trncga.SetText("本组答案：" + choiceGroupAnswer);
                                    trncga.FontFamily = "楷体";
                                    trncga.FontSize = 11;   // 比五号字略大
                                    trncga.IsBold = true;
                                    trncga.SetColor("ff0000");
                                }

                                var tp = m_Docx.CreateParagraph();
                                var tr = tp.CreateRun();
                                tr.SetText(q.OrderNumber + "．请阅读下列材料：");
                                tr.FontFamily = "宋体";
                                tr.FontSize = 11;   // 比五号字略大
                                tr.IsBold = true;

                                var clNum = 1;
                                foreach (var m in q.Materials)
                                {
                                    int indexOfcc = m.IndexOf("＜＜出处＞＞");
                                    if (indexOfcc >= 0)
                                    {
                                        string cl = Question.FormatText(m.Substring(0, indexOfcc));
                                        //sb.Append("<p class='ex_m_cl'>" + cl + "</p>");

                                        //var cp = m_Docx.CreateParagraph();
                                        //var cr = cp.CreateRun();
                                        //if (cl.StartsWith("＜＜材料＞＞"))
                                        //{
                                        //    cl = cl.Substring(6);
                                        //}
                                        //cr.SetText(cl);
                                        //cr.FontFamily = "楷体";
                                        //cr.FontSize = 11;   // 比五号字略大

                                        var indexOfLineBreak = cl.IndexOf("\n");
                                        if (indexOfLineBreak < 0 || (cl.Contains("｜") == false && cl.Contains("|") == false))
                                        {
                                            var cp = m_Docx.CreateParagraph();
                                            var crHeaderOfCl = cp.CreateRun();
                                            crHeaderOfCl.SetText("材料" + DateTimeConverter.YearToCn(clNum) + "　");
                                            crHeaderOfCl.FontFamily = "宋体";
                                            crHeaderOfCl.IsBold = true;
                                            crHeaderOfCl.FontSize = 11;  // 比五号字略大

                                            var cr = cp.CreateRun();
                                            if (cl.StartsWith("＜＜材料＞＞"))
                                            {
                                                cl = cl.Substring(6);
                                            }

                                            if (CustomMarkdownSupport.IsImageLinkLine(cl))
                                            {
                                                var imagePath = editor.GetRealPathFromImagelink(cl);
                                                if (System.IO.File.Exists(imagePath))
                                                {
                                                    double width, height;
                                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                    {
                                                        var img = Image.FromStream(gfs1);
                                                        width = img.Width;
                                                        height = img.Height;
                                                        ConvertImageSize(ref width, ref height);
                                                    }

                                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                    {
                                                        var c_p = m_Docx.Document.body.AddNewP();
                                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                                        var cpp = new XWPFParagraph(c_p, m_Docx);
                                                        var crr = cpp.CreateRun();
                                                        crr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                                        cpp.IndentationFirstLine = 0;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                cr.SetText(cl);
                                                clNum++;
                                                cr.FontFamily = "楷体";
                                                cr.FontSize = 11;   // 比五号字略大
                                                cr.IsBold = false;
                                            }
                                        }
                                        else
                                        {
                                            var fstLine = cl.Substring(0, indexOfLineBreak);
                                            var cp = m_Docx.CreateParagraph();
                                            var cr = cp.CreateRun();
                                            if (fstLine.StartsWith("＜＜材料＞＞"))
                                            {
                                                fstLine = fstLine.Substring(6);
                                            }
                                            cr.SetText(fstLine);
                                            cr.FontFamily = "楷体";
                                            cr.FontSize = 11;   // 比五号字略大

                                            var tail = cl.Substring(indexOfLineBreak);
                                            if (string.IsNullOrWhiteSpace(tail.Replace("\n", "")) == false)
                                            {
                                                var tailLines = tail.Split(new char[] { '\n', });
                                                var md = new MarkdownSharp.Markdown();
                                                var tableInfos = CustomMarkdownSupport.CompileTextTable(tailLines, ref md);


                                                for (int tIndex = 0; tIndex < tableInfos.Count; tIndex++)
                                                {
                                                    var ti = tableInfos[tIndex];
                                                    if (ti.TableLines.Count <= 0 || ti.ColumnAlignments.Count <= 0) continue;

                                                    XWPFTable tableContent = m_Docx.CreateTable(ti.TableLines.Count - ti.ColumnDefinitionLinesCount, ti.ColumnAlignments.Count);
                                                    var tableArray = m_Docx.Document.body.GetTblArray();
                                                    CT_Tbl m_CTTbl = tableArray[tableArray.Length - 1];  //获得文档中最新的表

                                                    m_CTTbl.AddNewTblPr().jc = new CT_Jc();
                                                    m_CTTbl.AddNewTblPr().jc.val = ST_Jc.center;//表在页面水平居中

                                                    TableLine preTableLine = null;
                                                    for (int li = 0; li < ti.TableLines.Count; li++)
                                                    {
                                                        var tl = ti.TableLines[li];
                                                        if (preTableLine == null)
                                                        {
                                                            preTableLine = tl;
                                                        }
                                                        else
                                                        {
                                                            if (tl.Type == TableLineType.MergeLine)
                                                            {
                                                                for (int ci = 0; ci < Math.Min(preTableLine.Cells.Count, tl.Cells.Count); ci++)
                                                                {
                                                                    preTableLine.Cells[ci] += tl.Cells[ci];
                                                                }
                                                            }
                                                            else if (tl.Type == TableLineType.Normal)
                                                            {
                                                                preTableLine = tl;
                                                            }
                                                        }  // 不考虑列定义行，统一居中。  
                                                    }

                                                    var cdLinesCount = 0;
                                                    for (int li = 0; li < ti.TableLines.Count; li++)
                                                    {
                                                        var tl = ti.TableLines[li];
                                                        if (tl.HeaderOrBodyType == HeaderOrBodyType.ColumnDifinition)
                                                        {
                                                            cdLinesCount++;
                                                            continue;
                                                        }

                                                        if (tl.Type == TableLineType.Normal)  // 合并的行已经合并上去了，可以直接忽略了。
                                                        {
                                                            var row = tableContent.GetRow(li - cdLinesCount);
                                                            for (int ci = 0; ci < tl.Cells.Count; ci++)
                                                            {
                                                                row.GetCell(ci).SetParagraph(SetCellText(m_Docx, tableContent, tl.Cells[ci], tl.HeaderOrBodyType == HeaderOrBodyType.HeaderLine));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        string clcc = m.Substring(indexOfcc + 6);
                                        if (clcc.StartsWith("——") == false)
                                        {
                                            clcc = "——" + clcc.Trim(new char[] { '→', });
                                        }

                                        clcc = Question.FormatText(clcc);

                                        if (string.IsNullOrEmpty(clcc.Trim(new char[] { ' ', '\t', '　', '—', })) == false)
                                        {
                                            var ccp = m_Docx.CreateParagraph();
                                            ccp.Alignment = ParagraphAlignment.RIGHT;
                                            var ccr = ccp.CreateRun();
                                            ccr.SetText(clcc);
                                            ccr.FontFamily = "楷体";
                                            ccr.FontSize = 11;   // 比五号字略大
                                        }
                                    }
                                    else
                                    {
                                        var cl = Question.FormatText(m);
                                        if (cl.StartsWith("＜＜材料＞＞"))
                                        {
                                            cl = cl.Substring(6);
                                        }

                                        if (CustomMarkdownSupport.IsImageLinkLine(cl))
                                        {
                                            var imagePath = editor.GetRealPathFromImagelink(cl);
                                            if (System.IO.File.Exists(imagePath))
                                            {
                                                double width, height;
                                                using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                {
                                                    var img = Image.FromStream(gfs1);
                                                    width = img.Width;
                                                    height = img.Height;
                                                    ConvertImageSize(ref width, ref height);
                                                }

                                                using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                {
                                                    var c_p = m_Docx.Document.body.AddNewP();
                                                    c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                                    var cpp = new XWPFParagraph(c_p, m_Docx);
                                                    var crr = cpp.CreateRun();
                                                    crr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                                    c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                                    cpp.IndentationFirstLine = 0;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            var cp = m_Docx.CreateParagraph();
                                            var crHeaderOfCl = cp.CreateRun();
                                            crHeaderOfCl.SetText("材料" + DateTimeConverter.YearToCn(clNum) + "　");
                                            crHeaderOfCl.FontFamily = "宋体";
                                            crHeaderOfCl.IsBold = true;
                                            crHeaderOfCl.FontSize = 11;  // 比五号字略大
                                            var cr = cp.CreateRun();
                                            cr.SetText(cl);
                                            clNum++;
                                            cr.FontFamily = "楷体";
                                            cr.FontSize = 11;   // 比五号字略大
                                            cr.IsBold = false;
                                        }
                                    }
                                }

                                var atp = m_Docx.CreateParagraph();
                                var atr = atp.CreateRun();
                                atr.SetText("请回答：");
                                atr.FontFamily = "宋体";
                                atr.FontSize = 11;   // 比五号字略大
                                atr.IsBold = true;

                                for (int i = 0; i < q.AsksList.Count; i++)
                                {
                                    var ap = m_Docx.CreateParagraph();
                                    ap.IndentationFirstLine = indent;
                                    var ar = ap.CreateRun();
                                    ar.SetText($"({i + 1}){q.AsksList[i]}");
                                    ar.FontFamily = "宋体";
                                    ar.FontSize = 11;   // 比五号字略大
                                }
                                break;
                            }
                        default:
                            {
                                if (withGroupAnswer && choiceGroupAnswer.Length > 0)
                                {
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();
                                    m_Docx.CreateParagraph();  // 加十个空行才够用
                                    var tpcga = m_Docx.CreateParagraph();
                                    var trncga = tpcga.CreateRun();
                                    trncga.SetText("本组答案：" + choiceGroupAnswer);
                                    trncga.FontFamily = "楷体";
                                    trncga.FontSize = 11;   // 比五号字略大
                                    trncga.IsBold = true;
                                    trncga.SetColor("ff0000");
                                }

                                var tp = m_Docx.CreateParagraph();
                                var tr = tp.CreateRun();
                                tr.SetText(q.OrderNumber + "．" + q.TitleString.Replace("\r\n", ""));
                                tr.FontFamily = "宋体";
                                tr.FontSize = 11;   // 比五号字略大
                                break;
                            }
                    }
                }

                #endregion 输出试卷

                #region 输出答题纸－必须——下次会被混淆，那就弄不清答案了。
                var linebreakePara1 = m_Docx.CreateParagraph();
                linebreakePara1.CreateRun().AddBreak();  // 分页符

                var title_answer_paper = m_Docx.CreateParagraph();
                title_answer_paper.Alignment = ParagraphAlignment.CENTER;
                var title_answer_paper_run = title_answer_paper.CreateRun();
                title_answer_paper_run.SetText(testpaper_title);
                title_answer_paper_run.FontFamily = "黑体";
                title_answer_paper_run.FontSize = 16;         // 三号字
                title_answer_paper_run.IsBold = true;

                var title_answer_paper2 = m_Docx.CreateParagraph();
                title_answer_paper2.Alignment = ParagraphAlignment.CENTER;
                var title_answer_paper2_run = title_answer_paper2.CreateRun();
                title_answer_paper2_run.SetText("答题纸");
                title_answer_paper2_run.FontFamily = "宋体";
                title_answer_paper2_run.FontSize = 22;
                title_answer_paper2_run.IsBold = true;

                var para_su = m_Docx.CreateParagraph();
                para_su.Alignment = ParagraphAlignment.CENTER;
                var para_su_run = para_su.CreateRun();
                para_su_run.SetText("第 I 卷　客观题部分");
                para_su_run.FontFamily = "黑体";
                para_su_run.FontSize = 16;
                para_su_run.IsBold = false;

                var para_su2 = m_Docx.CreateParagraph();
                para_su2.Alignment = ParagraphAlignment.CENTER;
                var para_su2_run = para_su2.CreateRun();
                para_su2.IndentationFirstLine = 0;
                para_su2_run.SetText("（请将客观题答案填涂到答题卡上对应位置。）");
                para_su2_run.FontFamily = "楷体";
                para_su2_run.FontSize = 11;
                para_su2_run.IsBold = false;

                var para_su3 = m_Docx.CreateParagraph();
                para_su3.Alignment = ParagraphAlignment.CENTER;
                var para_su3_run = para_su3.CreateRun();
                para_su3_run.SetText("第 II 卷　主观题部分");
                para_su3_run.FontFamily = "黑体";
                para_su3_run.FontSize = 16;
                para_su3_run.IsBold = false;

                foreach (var q2 in questions)
                {
                    switch (q2.Type)
                    {
                        case QuestionType.FillBlank:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var trn = tp.CreateRun();
                                trn.SetText(q2.OrderNumber + "．");
                                trn.FontFamily = "楷体";
                                trn.FontSize = 11;   // 比五号字略大
                                trn.IsBold = true;

                                var pieces = Utils.Text.SplitToPiecesByRegex(@"【.{1,}?】", q2.TitleString.Trim(trimChars));
                                foreach (var piece in pieces)
                                {
                                    var tfr = tp.CreateRun();
                                    if (piece.IsMartchText)
                                    {
                                        tfr.SetText(ConvertToBlank(piece.SourceText));
                                        tfr.SetUnderline(UnderlinePatterns.Single);
                                    }
                                    else
                                    {
                                        tfr.SetText(piece.SourceText);
                                    }
                                    tfr.FontFamily = "楷体";
                                    tfr.FontSize = 11;
                                    tfr.IsBold = true;
                                }

                                // 答题纸上不加图像
                                break;
                            }
                        case QuestionType.Subjective:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var tr = tp.CreateRun();
                                tr.SetText(q2.OrderNumber + "．请回答：");
                                tr.FontFamily = "宋体";
                                tr.FontSize = 11;   // 比五号字略大
                                tr.IsBold = true;

                                for (int i = 0; i < q2.AsksList.Count; i++)
                                {
                                    var ap = m_Docx.CreateParagraph();
                                    ap.IndentationFirstLine = indent;
                                    var ar = ap.CreateRun();
                                    ar.SetText($"({i + 1}){q2.AsksList[i]}");
                                    ar.FontFamily = "宋体";
                                    ar.FontSize = 11;   // 比五号字略大
                                }
                                break;
                            }
                        default:
                            {
                                continue;  // 不在答题纸上打印客观题。
                            }
                    }
                }
                #endregion 输出答题纸

                #region 输出答案（教师版）－必须——下次会被混淆，那就弄不清答案了。
                var linebreakePara2 = m_Docx.CreateParagraph();
                linebreakePara2.CreateRun().AddBreak();  // 分页符

                var title_answer_para = m_Docx.CreateParagraph();
                title_answer_para.Alignment = ParagraphAlignment.CENTER;
                var title_answer_run = title_answer_para.CreateRun();
                title_answer_run.SetText(testpaper_title + " - 参考答案");
                title_answer_run.FontFamily = "宋体";
                title_answer_run.FontSize = 16;  // 三号字
                title_answer_run.IsBold = true;

                if (choiceAnswersText.Length > 0)
                {
                    var cap = m_Docx.CreateParagraph();
                    cap.Alignment = ParagraphAlignment.LEFT;
                    var car = cap.CreateRun();
                    car.SetText($"客观题参考答案：");
                    car.FontFamily = "宋体";
                    car.FontSize = 11;
                    car.SetColor("ff0000");

                    var calines = choiceAnswersText.ToString().Split(new char[] { '\r', '\n', }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var caline in calines)
                    {
                        var calp = m_Docx.CreateParagraph();
                        calp.Alignment = ParagraphAlignment.LEFT;
                        calp.IndentationFirstLine = indent;
                        var calr = calp.CreateRun();
                        calr.SetText(caline);
                        calr.FontFamily = "宋体";
                        calr.FontSize = 11;
                        calr.SetColor("ff0000");
                    }
                    m_Docx.CreateParagraph();
                }

                foreach (var q in questions)
                {
                    switch (q.Type)
                    {
                        case QuestionType.Choice:
                        case QuestionType.Judge:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var trn = tp.CreateRun();
                                trn.SetText(q.OrderNumber + "．");
                                trn.FontFamily = "楷体";
                                trn.FontSize = 11;   // 比五号字略大
                                trn.IsBold = true;

                                var baseTitle = q.TitleString.Replace("\r", "");
                                var indexOfLineBreak = baseTitle.IndexOf("\n");

                                if (indexOfLineBreak < 0 || (q.TitleString.Contains("｜") == false && q.TitleString.Contains("|") == false))
                                {
                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"(?<=【).{1,}?(?=】)", q.TitleString.Trim(trimChars));
                                    foreach (var piece in pieces)
                                    {
                                        var tr = tp.CreateRun();
                                        if (piece.IsMartchText)
                                        {
                                            tr.SetText("  ");
                                        }
                                        else
                                        {
                                            tr.SetText(piece.SourceText.Replace("\\_", "_"));
                                        }
                                        tr.FontFamily = "楷体";
                                        tr.FontSize = 11;
                                        tr.IsBold = true;
                                    }
                                }
                                else
                                {
                                    var fstLine = baseTitle.Substring(0, indexOfLineBreak);

                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"(?<=【).{1,}?(?=】)", fstLine.Trim(trimChars));
                                    foreach (var piece in pieces)
                                    {
                                        var tr = tp.CreateRun();
                                        if (piece.IsMartchText)
                                        {
                                            tr.SetText("  ");
                                        }
                                        else
                                        {
                                            tr.SetText(piece.SourceText.Replace("\\_", "_"));
                                        }
                                        tr.FontFamily = "楷体";
                                        tr.FontSize = 11;
                                        tr.IsBold = true;
                                    }

                                    var lines = baseTitle.Substring(indexOfLineBreak).Split(new char[] { '\n', }, StringSplitOptions.None);
                                    var md = new MarkdownSharp.Markdown();
                                    var tableInfos = CustomMarkdownSupport.CompileTextTable(lines, ref md);

                                    for (int tIndex = 0; tIndex < tableInfos.Count; tIndex++)
                                    {
                                        var ti = tableInfos[tIndex];
                                        if (ti.TableLines.Count <= 0 || ti.ColumnAlignments.Count <= 0) continue;

                                        XWPFTable tableContent = m_Docx.CreateTable(ti.TableLines.Count - ti.ColumnDefinitionLinesCount, ti.ColumnAlignments.Count);
                                        var tableArray = m_Docx.Document.body.GetTblArray();
                                        CT_Tbl m_CTTbl = tableArray[tableArray.Length - 1];  //获得文档中最新的表

                                        m_CTTbl.AddNewTblPr().jc = new CT_Jc();
                                        m_CTTbl.AddNewTblPr().jc.val = ST_Jc.center;//表在页面水平居中

                                        TableLine preTableLine = null;
                                        for (int li = 0; li < ti.TableLines.Count; li++)
                                        {
                                            var tl = ti.TableLines[li];
                                            if (preTableLine == null)
                                            {
                                                preTableLine = tl;
                                            }
                                            else
                                            {
                                                if (tl.Type == TableLineType.MergeLine)
                                                {
                                                    for (int ci = 0; ci < Math.Min(preTableLine.Cells.Count, tl.Cells.Count); ci++)
                                                    {
                                                        preTableLine.Cells[ci] += tl.Cells[ci];
                                                    }
                                                }
                                                else if (tl.Type == TableLineType.Normal)
                                                {
                                                    preTableLine = tl;
                                                }
                                            }  // 不考虑列定义行，统一居中。  
                                        }

                                        var cdLinesCount = 0;
                                        for (int li = 0; li < ti.TableLines.Count; li++)
                                        {
                                            var tl = ti.TableLines[li];
                                            if (tl.HeaderOrBodyType == HeaderOrBodyType.ColumnDifinition)
                                            {
                                                cdLinesCount++;
                                                continue;
                                            }

                                            if (tl.Type == TableLineType.Normal)  // 合并的行已经合并上去了，可以直接忽略了。
                                            {
                                                var row = tableContent.GetRow(li - cdLinesCount);
                                                for (int ci = 0; ci < tl.Cells.Count; ci++)
                                                {
                                                    tableContent.GetRow(li - cdLinesCount).GetCell(ci).SetParagraph(SetCellText(m_Docx, tableContent, tl.Cells[ci], tl.HeaderOrBodyType == HeaderOrBodyType.HeaderLine));
                                                }
                                            }
                                        }
                                    }
                                }

                                var imagePath = editor.GetRealPathFromRelativeImagePath(q.MarkdownImagePath);
                                if (System.IO.File.Exists(imagePath))
                                {
                                    double width, height;
                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var img = Image.FromStream(gfs1);
                                        width = img.Width;
                                        height = img.Height;
                                        ConvertImageSize(ref width, ref height);
                                    }

                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var c_p = m_Docx.Document.body.AddNewP();
                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                        var cp = new XWPFParagraph(c_p, m_Docx);
                                        var cr = cp.CreateRun();
                                        cr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                        cp.IndentationFirstLine = 0;
                                    }
                                }

                                foreach (var ci in q.ChoiceItems)
                                {
                                    var bp = m_Docx.CreateParagraph();
                                    bp.IndentationFirstLine = indent;
                                    var brn = bp.CreateRun();
                                    brn.SetText(ConvertToAlphaNumber(ci.OrderNumber) + "．");
                                    brn.FontFamily = "宋体";
                                    brn.FontSize = 11;
                                    var br = bp.CreateRun();
                                    br.SetText(ci.Text.Replace("\r\n", ""));
                                    br.FontFamily = "宋体";
                                    br.FontSize = 11;
                                    if (ci.IsAnswer)
                                    {
                                        brn.SetColor("ff0000");
                                        br.SetColor("ff0000");
                                        br.IsBold = true;
                                    }

                                    if (string.IsNullOrWhiteSpace(ci.AnalysisText) == false)
                                    {
                                        var bpa = m_Docx.CreateParagraph();
                                        bpa.IndentationFirstLine = indent;
                                        var bra = bpa.CreateRun();
                                        if (ci.IsAnswer)
                                        {
                                            bra.SetText($"★ {ci.AnalysisText.Trim(trimChars)}");
                                        }
                                        else
                                        {
                                            bra.SetText($"☆ {ci.AnalysisText.Trim(trimChars)}");
                                        }
                                        bra.FontFamily = "楷体";
                                        bra.FontSize = 11;
                                        bra.SetColor("162589");  // 深蓝
                                    }
                                }
                                break;
                            }
                        case QuestionType.FillBlank:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var trn = tp.CreateRun();
                                trn.SetText(q.OrderNumber + "．");
                                trn.FontFamily = "楷体";
                                trn.FontSize = 11;   // 比五号字略大
                                trn.IsBold = true;

                                var pieces = Utils.Text.SplitToPiecesByRegex(@"【[ 　\t]{1,}?】", q.TitleString.Trim(trimChars));
                                foreach (var piece in pieces)
                                {
                                    var tfr = tp.CreateRun();
                                    if (piece.IsMartchText)
                                    {
                                        tfr.SetText(ConvertToBlank(piece.SourceText));
                                        tfr.SetUnderline(UnderlinePatterns.Single);
                                    }
                                    else
                                    {
                                        tfr.SetText(piece.SourceText);
                                    }
                                    tfr.FontFamily = "楷体";
                                    tfr.FontSize = 11;
                                    tfr.IsBold = true;
                                }

                                var imagePath = editor.GetRealPathFromRelativeImagePath(q.MarkdownImagePath);
                                if (System.IO.File.Exists(imagePath))
                                {
                                    double width, height;
                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var img = Image.FromStream(gfs1);
                                        width = img.Width;
                                        height = img.Height;
                                        ConvertImageSize(ref width, ref height);
                                    }

                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                    {
                                        var c_p = m_Docx.Document.body.AddNewP();
                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                        var cp = new XWPFParagraph(c_p, m_Docx);
                                        var cr = cp.CreateRun();
                                        cr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                        cp.IndentationFirstLine = 0;
                                    }
                                }

                                var tpa = m_Docx.CreateParagraph();
                                var tra = tpa.CreateRun();
                                tra.SetText($"★ {q.Answer}");
                                tra.FontFamily = "楷体";
                                tra.FontSize = 11;
                                tra.IsItalic = true;
                                tra.SetColor("ff0000");
                                break;
                            }
                        case QuestionType.Subjective:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var tr = tp.CreateRun();
                                tr.SetText(q.OrderNumber + "．请阅读下列材料：");
                                tr.FontFamily = "宋体";
                                tr.FontSize = 11;   // 比五号字略大
                                tr.IsBold = true;

                                foreach (var m in q.Materials)
                                {
                                    int indexOfcc = m.IndexOf("＜＜出处＞＞");
                                    if (indexOfcc >= 0)
                                    {
                                        string cl = Question.FormatText(m.Substring(0, indexOfcc)).Replace("\r", "");
                                        //sb.Append("<p class='ex_m_cl'>" + cl + "</p>");

                                        var indexOfLineBreak = cl.IndexOf("\n");
                                        if (indexOfLineBreak < 0 || (cl.Contains("｜") == false && cl.Contains("|") == false))
                                        {
                                            var cp = m_Docx.CreateParagraph();
                                            var cr = cp.CreateRun();
                                            if (cl.StartsWith("＜＜材料＞＞"))
                                            {
                                                cl = cl.Substring(6);
                                            }

                                            if (CustomMarkdownSupport.IsImageLinkLine(cl))
                                            {
                                                var imagePath = editor.GetRealPathFromImagelink(cl);
                                                if (System.IO.File.Exists(imagePath))
                                                {
                                                    double width, height;
                                                    using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                    {
                                                        var img = Image.FromStream(gfs1);
                                                        width = img.Width;
                                                        height = img.Height;
                                                        ConvertImageSize(ref width, ref height);
                                                    }

                                                    using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                    {
                                                        var c_p = m_Docx.Document.body.AddNewP();
                                                        c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                                        var cpp = new XWPFParagraph(c_p, m_Docx);
                                                        var crr = cpp.CreateRun();
                                                        crr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                                        c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                                        cpp.IndentationFirstLine = 0;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                cr.SetText(cl);
                                                cr.FontFamily = "楷体";
                                                cr.FontSize = 11;   // 比五号字略大
                                            }
                                        }
                                        else
                                        {
                                            var fstLine = cl.Substring(0, indexOfLineBreak);
                                            var cp = m_Docx.CreateParagraph();
                                            var cr = cp.CreateRun();
                                            if (fstLine.StartsWith("＜＜材料＞＞"))
                                            {
                                                fstLine = fstLine.Substring(6);
                                            }
                                            cr.SetText(fstLine);
                                            cr.FontFamily = "楷体";
                                            cr.FontSize = 11;   // 比五号字略大

                                            var tail = cl.Substring(indexOfLineBreak);
                                            if (string.IsNullOrWhiteSpace(tail.Replace("\n", "")) == false)
                                            {
                                                var tailLines = tail.Split(new char[] { '\n', });
                                                var md = new MarkdownSharp.Markdown();
                                                var tableInfos = CustomMarkdownSupport.CompileTextTable(tailLines, ref md);


                                                for (int tIndex = 0; tIndex < tableInfos.Count; tIndex++)
                                                {
                                                    var ti = tableInfos[tIndex];
                                                    if (ti.TableLines.Count <= 0 || ti.ColumnAlignments.Count <= 0) continue;

                                                    XWPFTable tableContent = m_Docx.CreateTable(ti.TableLines.Count - ti.ColumnDefinitionLinesCount, ti.ColumnAlignments.Count);
                                                    var tableArray = m_Docx.Document.body.GetTblArray();
                                                    CT_Tbl m_CTTbl = tableArray[tableArray.Length - 1];  //获得文档中最新的表

                                                    m_CTTbl.AddNewTblPr().jc = new CT_Jc();
                                                    m_CTTbl.AddNewTblPr().jc.val = ST_Jc.center;//表在页面水平居中

                                                    TableLine preTableLine = null;
                                                    for (int li = 0; li < ti.TableLines.Count; li++)
                                                    {
                                                        var tl = ti.TableLines[li];
                                                        if (preTableLine == null)
                                                        {
                                                            preTableLine = tl;
                                                        }
                                                        else
                                                        {
                                                            if (tl.Type == TableLineType.MergeLine)
                                                            {
                                                                for (int ci = 0; ci < Math.Min(preTableLine.Cells.Count, tl.Cells.Count); ci++)
                                                                {
                                                                    preTableLine.Cells[ci] += tl.Cells[ci];
                                                                }
                                                            }
                                                            else if (tl.Type == TableLineType.Normal)
                                                            {
                                                                preTableLine = tl;
                                                            }
                                                        }  // 不考虑列定义行，统一居中。  
                                                    }

                                                    var cdLinesCount = 0;
                                                    for (int li = 0; li < ti.TableLines.Count; li++)
                                                    {
                                                        var tl = ti.TableLines[li];
                                                        if (tl.HeaderOrBodyType == HeaderOrBodyType.ColumnDifinition)
                                                        {
                                                            cdLinesCount++;
                                                            continue;
                                                        }

                                                        if (tl.Type == TableLineType.Normal)  // 合并的行已经合并上去了，可以直接忽略了。
                                                        {
                                                            var row = tableContent.GetRow(li - cdLinesCount);
                                                            for (int ci = 0; ci < tl.Cells.Count; ci++)
                                                            {
                                                                tableContent.GetRow(li - cdLinesCount).GetCell(ci).SetParagraph(SetCellText(m_Docx, tableContent, tl.Cells[ci], tl.HeaderOrBodyType == HeaderOrBodyType.HeaderLine));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        string clcc = m.Substring(indexOfcc + 6);
                                        if (clcc.StartsWith("——") == false)
                                        {
                                            clcc = "——" + clcc;
                                        }

                                        clcc = Question.FormatText(clcc);

                                        if (string.IsNullOrEmpty(clcc.Trim(new char[] { ' ', '\t', '　', '—', })) == false)
                                        {
                                            var ccp = m_Docx.CreateParagraph();
                                            ccp.Alignment = ParagraphAlignment.RIGHT;
                                            var ccr = ccp.CreateRun();
                                            ccr.SetText(clcc);
                                            ccr.FontFamily = "楷体";
                                            ccr.FontSize = 11;   // 比五号字略大
                                        }
                                    }
                                    else
                                    {
                                        var cl = Question.FormatText(m);
                                        var cp = m_Docx.CreateParagraph();
                                        var cr = cp.CreateRun();
                                        if (cl.StartsWith("＜＜材料＞＞"))
                                        {
                                            cl = cl.Substring(6);
                                        }

                                        if (CustomMarkdownSupport.IsImageLinkLine(cl))
                                        {
                                            var imagePath = editor.GetRealPathFromImagelink(cl);
                                            if (System.IO.File.Exists(imagePath))
                                            {
                                                double width, height;
                                                using (var gfs1 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                {
                                                    var img = Image.FromStream(gfs1);
                                                    width = img.Width;
                                                    height = img.Height;
                                                    ConvertImageSize(ref width, ref height);
                                                }

                                                using (var gfs2 = new System.IO.FileStream(imagePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                                {
                                                    var c_p = m_Docx.Document.body.AddNewP();
                                                    c_p.AddNewPPr().AddNewJc().val = ST_Jc.center;
                                                    var cpp = new XWPFParagraph(c_p, m_Docx);
                                                    var crr = cpp.CreateRun();
                                                    crr.AddPicture(gfs2, 4, "img", (int)width, (int)height);  // 默认14cm，1cm = 360000 EMUS（English Metric Unit）;
                                                    c_p.AddNewPPr().AddNewSpacing().lineRule = ST_LineSpacingRule.auto;
                                                    cpp.IndentationFirstLine = 0;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            cr.SetText(cl);
                                            cr.FontFamily = "楷体";
                                            cr.FontSize = 11;   // 比五号字略大
                                        }
                                    }
                                }

                                var atp = m_Docx.CreateParagraph();
                                var atr = atp.CreateRun();
                                atr.SetText("请回答：");
                                atr.FontFamily = "宋体";
                                atr.FontSize = 11;   // 比五号字略大
                                atr.IsBold = true;

                                for (int i = 0; i < q.AsksList.Count; i++)
                                {
                                    var ap = m_Docx.CreateParagraph();
                                    ap.IndentationFirstLine = indent;
                                    var ar = ap.CreateRun();
                                    ar.SetText($"({i + 1}){q.AsksList[i]}");
                                    ar.FontFamily = "宋体";
                                    ar.FontSize = 11;   // 比五号字略大
                                }

                                var atpa = m_Docx.CreateParagraph();
                                var atra = atpa.CreateRun();
                                atra.SetText("参考答案：");
                                atra.FontFamily = "宋体";
                                atra.FontSize = 11;
                                atra.IsBold = true;

                                for (int i = 0; i < q.Answers.Count; i++)
                                {
                                    var pieces = Utils.Text.SplitToPiecesByRegex(@"\<br {0,}?\/?\>", q.Answers[i], false, true);
                                    var realCount = 0;
                                    foreach (var piece in pieces)
                                    {
                                        if (string.IsNullOrWhiteSpace(piece.SourceText)) continue;
                                        realCount++;
                                    }

                                    if (realCount == 1)
                                    {
                                        var ap = m_Docx.CreateParagraph();
                                        ap.IndentationFirstLine = indent;
                                        var ar = ap.CreateRun();
                                        ar.SetText($"({i + 1}){q.Answers[i]}");
                                        ar.FontFamily = "楷体";
                                        ar.FontSize = 11;   // 比五号字略大
                                    }
                                    else if (realCount > 1)
                                    {
                                        for (int pi = 0; pi < pieces.Count; pi++)
                                        {
                                            if (string.IsNullOrWhiteSpace(pieces[pi].SourceText)) continue;
                                            if (pi == 0)
                                            {
                                                var ap = m_Docx.CreateParagraph();
                                                ap.IndentationFirstLine = indent;
                                                var ar = ap.CreateRun();
                                                ar.SetText($"({i + 1}){pieces[pi].SourceText}");
                                                ar.FontFamily = "楷体";
                                                ar.FontSize = 11;   // 比五号字略大
                                            }
                                            else
                                            {
                                                var ap = m_Docx.CreateParagraph();
                                                ap.IndentationFirstLine = indent;
                                                var ar = ap.CreateRun();
                                                ar.SetText("　　" + pieces[pi].SourceText);
                                                ar.FontFamily = "楷体";
                                                ar.FontSize = 11;   // 比五号字略大
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                        default:
                            {
                                var tp = m_Docx.CreateParagraph();
                                var tr = tp.CreateRun();
                                tr.SetText(q.OrderNumber + "．" + q.TitleString.Replace("\r\n", ""));
                                tr.FontFamily = "宋体";
                                tr.FontSize = 11;   // 比五号字略大
                                break;
                            }
                    }
                }
                #endregion 输出教师版

                // 写 Word 试卷文档
                using (var sw = System.IO.File.Create(sfd.FileName))
                {
                    m_Docx.Write(sw);
                }

                var answer = LMessageBox.Show($"文件已导出至：\r\n\r\n　　{sfd.FileName}。\r\n\r\n　　要尝试打开吗？",
                    Globals.AppName, System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Question);
                if (answer == System.Windows.MessageBoxResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe",
                        (sfd.FileName.Contains(' ') ? ("\"" + sfd.FileName + "\"") : sfd.FileName));
                }
            }
            catch (Exception ex)
            {
                if (ex == null)
                {
                    LMessageBox.ShowWarning("发生未知错误！");
                    return;
                }

                if (string.IsNullOrWhiteSpace(ex.Message))
                {
                    if (ex.InnerException != null)
                    {
                        LMessageBox.ShowWarning(ex.InnerException.Message);
                        return;
                    }

                    LMessageBox.ShowWarning("发生未知内部错误！");
                    return;
                }

                LMessageBox.ShowWarning(ex.Message);
            }
        }

        /// <summary>
        /// 设置字体样式版权声明：本文为CSDN博主「dengxt」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。
        /// 原文链接：https://blog.csdn.net/dengxt/java/article/details/84750867
        /// </summary>        
        public static XWPFParagraph SetCellText(XWPFDocument doc, XWPFTable table, string setText, bool isHeaderCell = false)
        {
            //table中的文字格式设置  
            CT_P para = new CT_P();
            XWPFParagraph pCell = new XWPFParagraph(para, table.Body);
            pCell.Alignment = ParagraphAlignment.CENTER;//字体居中  
            pCell.VerticalAlignment = NPOI.XWPF.UserModel.TextAlignment.CENTER;//字体居中  

            XWPFRun r1c1 = pCell.CreateRun();
            r1c1.Paragraph.IndentFromLeft = 55;
            r1c1.Paragraph.IndentFromRight = 55;
            r1c1.SetText(setText);
            r1c1.FontSize = 11;
            r1c1.FontFamily = "新宋体";
            if (isHeaderCell)
            {
                r1c1.IsBold = true;
            }
            //r1c1.SetTextPosition(20);//设置高度  
            return pCell;
        }

        /// <summary>
        /// 给字符串尾部添加一些半角空格，保证整个字符串宽度为指定宽度（这里的宽度以半角宽度计算）。
        /// </summary>
        /// <param name="txt">源文本。</param>
        /// <param name="maxWidth">在尾部添加空格后，字符串应当是这个宽度。</param>
        /// <returns></returns>
        public static string AppendBlanks(string txt, int maxWidth)
        {
            if (string.IsNullOrWhiteSpace(txt))
            {
                return new string(' ', maxWidth);
            }

            var len = GetTextWidth(txt);
            if (len >= maxWidth) return txt;

            return txt + new string(' ', maxWidth - len);
        }

        /// <summary>
        /// 取文本宽度。
        /// </summary>
        /// <param name="text">要取宽度的文本</param>
        /// <param name="trimStartAndEnd">是否去除首尾空格。</param>
        /// <returns></returns>
        public static int GetTextWidth(string text, bool trimStartAndEnd = false)
        {
            if (string.IsNullOrEmpty(text)) return 0;

            if (trimStartAndEnd) text = text.Trim(new char[] { ' ', '　', '\t', });

            int width = 0;
            foreach (char c in text)
            {
                width += Encoding.Default.GetByteCount(new char[] { c });//判断全、半角不需要再手工做了。
            }

            return width;
        }

        private static string ReplaceWithUnderLine(string src)
        {
            if (string.IsNullOrEmpty(src)) return string.Empty;

            var sb = new StringBuilder();
            for (int i = 0; i <= src.Length; i++)//多加一对半角下划线字符。
            {
                sb.Append("__");
            }

            return sb.ToString();
        }

        /// <summary>
        /// 根据试题列表提取出其中的试题文本。
        /// </summary>
        /// <param name="questions"></param>
        /// <param name="sbAll">教师版。</param>
        /// <param name="sbAnswerLetters">选择题答案字符串。</param>
        /// <param name="sbQuestion">学生版。</param>
        /// <param name="sbAnalysysAndAnswer">答案和解析。</param>
        public static void ExportQuestionsFromText(ref List<Question> questions, out StringBuilder sbAll, out StringBuilder sbAnswerLetters, out StringBuilder sbQuestion, out StringBuilder sbAnalysysAndAnswer)
        {
            sbAll = new StringBuilder();
            sbAnswerLetters = new StringBuilder();
            int letterCount = 0;

            //这两个用于学生版。
            sbQuestion = new StringBuilder();
            sbAnalysysAndAnswer = new StringBuilder();
            var trimChars = new char[] { '\r', '\n', ' ', '　', '\t', };
            for (int indexOfQuestion = 0; indexOfQuestion < questions.Count; indexOfQuestion++)
            {
                var q = questions[indexOfQuestion];

                switch (q.Type)
                {
                    case QuestionType.Choice:
                    case QuestionType.Judge:
                        {
                            //带一对方括弧的是填充项。
                            string title = q.TitleString.Replace("\\_", "_");

                            //根据title生成段落。
                            int startBracket, endBracket;
                            startBracket = title.IndexOf("【");
                            endBracket = title.IndexOf("】");

                            if (startBracket < 0 || endBracket < 0) break;

                            //题号
                            sbAll.Append("\r\n");  // 每题前面空一行。
                            var numberTxt = (indexOfQuestion + 1).ToString() + "．";
                            sbAll.Append(numberTxt);

                            //题号
                            sbQuestion.Append("\r\n");  // 每题前面空一行。
                            sbQuestion.Append(numberTxt);
                            sbAnalysysAndAnswer.Append(numberTxt);

                            string titleText = title.Substring(0, startBracket) + "（　）" + title.Substring(endBracket + 1);
                            titleText = titleText.Trim(trimChars) + "\r\n";

                            sbAll.Append(titleText);
                            sbQuestion.Append(titleText);

                            //添加各选项

                            //先需要混淆下顺序，否则会总选A了。
                            int[] randomArray = L.GetRandomIntArray(q.ChoiceItems.Count);
                            for (int i = 0; i < randomArray.Length; i++)
                            {
                                var qi = q.ChoiceItems[i];
                                qi.OrderNumber = randomArray[i];
                            }

                            q.ChoiceItems.Sort(new ComparsionQuestionItem());

                            string answerHeaderText = "未设置答案项";

                            for (int i = 0; i < q.ChoiceItems.Count; i++)
                            {
                                ChoiceItem qi = q.ChoiceItems[i];
                                string choiceItemHeaderText = L.ConvertToAlpha(i + 1);

                                sbAll.Append(choiceItemHeaderText);
                                sbAll.Append(qi.Text.Trim(trimChars));
                                sbAll.Append("\r\n");

                                sbQuestion.Append(choiceItemHeaderText);
                                sbQuestion.Append(qi.Text.Trim(trimChars));
                                sbQuestion.Append("\r\n");

                                string analysis = qi.AnalysisText.Replace("\r\n", "").Replace("此项", L.ConvertToAlpha(i + 1) + "项");
                                if (new Regex(@"^([A-Z]\.[　 ]{0,}){2,2}").Match(analysis).Success)
                                    analysis = analysis.Substring(2).TrimStart(new char[] { '　', ' ', });

                                if (qi.IsAnswer)
                                {
                                    answerHeaderText = choiceItemHeaderText.Replace(".", "");
                                    sbAnswerLetters.Append(answerHeaderText);
                                    letterCount++;
                                    if (letterCount == 5)
                                    {
                                        sbAnswerLetters.Append(" ");
                                        letterCount = 0;
                                    }
                                }
                                if (string.IsNullOrEmpty(analysis) == false)
                                {
                                    sbAll.Append(qi.IsAnswer ? "◆" : "- ");
                                    sbAll.Append(analysis);
                                    sbAll.Append("\r\n");
                                }

                                sbAnalysysAndAnswer.Append(choiceItemHeaderText);
                                sbAnalysysAndAnswer.Append(string.IsNullOrEmpty(analysis) ? "<...>" : analysis);
                                sbAnalysysAndAnswer.Append("\r\n");
                            }

                            // 取消每题之间的空行。
                            //sbAll.Append("\r\n\r\n");
                            //sbQuestion.Append("\r\n\r\n");//每题之间空一行。

                            sbAnalysysAndAnswer.Append("----------\r\n【答案】" + answerHeaderText + "。\r\n\r\n");
                            break;
                        }
                    case QuestionType.FillBlank:
                        {
                            string answerHeaderText = "";

                            string title = q.TitleString;
                            int previewStartBacket = -1; int previewEndBracket = -1;
                            int startBracket, endBracket;
                            startBracket = title.IndexOf("【");
                            endBracket = title.IndexOf("】");

                            if (startBracket < 0 || endBracket < 0) break;

                            //题号
                            sbQuestion.Append((indexOfQuestion + 1).ToString() + "．");
                            sbAnalysysAndAnswer.Append((indexOfQuestion + 1).ToString() + "．");

                            int answerPieceNumber = 1;

                            while (startBracket >= 0 && endBracket >= 0)
                            {
                                sbQuestion.Append(title.Substring(previewEndBracket + 1, startBracket - previewEndBracket - 1));
                                string answerPiece = title.Substring(startBracket + 1, endBracket - startBracket - 1);
                                sbQuestion.Append(ReplaceWithUnderLine(answerPiece));

                                answerHeaderText += "[" + answerPieceNumber.ToString() + "]" + answerPiece + "　";

                                previewEndBracket = endBracket;
                                previewStartBacket = startBracket;

                                startBracket = title.IndexOf("【", endBracket + 1);
                                endBracket = title.IndexOf("】", endBracket + 1);

                                answerPieceNumber++;
                            }

                            sbQuestion.Append(title.Substring(previewEndBracket + 1) + "\r\n");

                            sbAnalysysAndAnswer.Append("【答案】" + answerHeaderText.Substring(0, answerHeaderText.Length - 1) + "。\r\n\r\n");

                            break;
                        }
                    case QuestionType.Subjective:
                        {
                            string title = q.TitleString.Replace("\r\n", "");

                            if (string.IsNullOrEmpty(title))
                            {
                                title = "阅读下列材料：";
                            }
                            //根据title生成段落。
                            sbQuestion.Append((indexOfQuestion + 1).ToString() + "．");
                            sbQuestion.Append(title);

                            //材料部分。

                            foreach (var s in q.Materials)
                            {
                                int indexOfcc = s.IndexOf("＜＜出处＞＞");
                                if (indexOfcc >= 0)
                                {
                                    sbQuestion.Append(s.Substring(0, indexOfcc).Replace("\r\n", "") + "\r\n");

                                    string clcc = s.Substring(indexOfcc + 6);
                                    if (clcc.StartsWith("——") == false)
                                    {
                                        clcc = "——" + clcc;
                                    }
                                    sbQuestion.Append(clcc + "\r\n");
                                }
                                else
                                {
                                    var cl = s;
                                    if (s.StartsWith("＜＜材料＞＞"))
                                    {
                                        cl = s.Substring(6);
                                    }
                                    sbQuestion.Append(cl.Replace("\r\n", "") + "\r\n");
                                }
                            }

                            sbQuestion.Append("请回答：\r\n");

                            //问题部分

                            for (int i = 0; i < q.AsksList.Count; i++)
                            {
                                var s = q.AsksList[i];
                                sbQuestion.Append("(" + (i + 1).ToString() + ")" + s.Replace("\r\n", "") + "\r\n");
                            }

                            sbQuestion.Append("\r\n");

                            //下面是答案部分。
                            sbAnalysysAndAnswer.Append((indexOfQuestion + 1) + "．");
                            for (int i = 0; i < q.Answers.Count; i++)
                            {
                                var s = q.Answers[i];
                                int indexOfjx = s.IndexOf("解析＞＞");
                                if (indexOfjx >= 0)
                                {
                                    sbAnalysysAndAnswer.Append("(" + (i + 1).ToString() + ")" + s.Substring(0, indexOfjx).Replace("\r\n", ""));
                                    sbAnalysysAndAnswer.Append(s.Substring(indexOfjx + 6));
                                }
                                else
                                {
                                    sbAnalysysAndAnswer.Append("(" + (i + 1).ToString() + ")" + s.Replace("\r\n", ""));
                                }
                            }
                            sbAnalysysAndAnswer.Append("\r\n\r\n");
                            break;
                        }
                }
            }
        }

        /// <summary>
        /// 提取单选题成赛事星导入模板。
        /// </summary>
        public static void ExportQuestionsForSaiShiXing(ref List<Question> questions, out StringBuilder sbAll)
        {
            sbAll = new StringBuilder();
            var sbAnswerLetters = new StringBuilder();
            int letterCount = 0;

            //这两个用于学生版。
            var trimChars = new char[] { '\r', '\n', ' ', '　', '\t', };
            for (int indexOfQuestion = 0; indexOfQuestion < questions.Count; indexOfQuestion++)
            {
                var q = questions[indexOfQuestion];
                sbAll.Append("1");  // 试题所属栏目
                sbAll.Append("\t");

                sbAll.Append("单选");
                sbAll.Append("\t");

                sbAll.Append("5");  // 单题分值
                sbAll.Append("\t");

                switch (q.Type)
                {
                    case QuestionType.Choice:
                    case QuestionType.Judge:
                        {
                            //带一对方括弧的是填充项。
                            string title = q.TitleString.Replace("\\_", "_");

                            //根据title生成段落。
                            int startBracket, endBracket;
                            startBracket = title.IndexOf("【");
                            endBracket = title.IndexOf("】");

                            if (startBracket < 0 || endBracket < 0) break;

                            string titleText = title.Substring(0, startBracket) + "（　）" + title.Substring(endBracket + 1);
                            titleText = titleText.Trim(trimChars);

                            sbAll.Append(titleText);   // 题干
                            sbAll.Append("\t");

                            sbAll.Append("\t");   // 忽略知识点

                            //添加各选项

                            //先需要混淆下顺序，否则会总选A了。
                            int[] randomArray = L.GetRandomIntArray(q.ChoiceItems.Count);
                            for (int i = 0; i < randomArray.Length; i++)
                            {
                                var qi = q.ChoiceItems[i];
                                qi.OrderNumber = randomArray[i];
                            }

                            q.ChoiceItems.Sort(new ComparsionQuestionItem());

                            string answerHeaderText = "未设置答案项";
                            var sbAnalysis = new StringBuilder();
                            List<string> cilist = new List<string>();
                            for (int i = 0; i < q.ChoiceItems.Count; i++)
                            {
                                ChoiceItem qi = q.ChoiceItems[i];
                                string choiceItemHeaderText = L.ConvertToAlpha(i + 1);
                                cilist.Add(qi.Text.Trim(trimChars));

                                string analysis = qi.AnalysisText.Replace("\r\n", "").Replace("此项", choiceItemHeaderText + "项");
                                if (new Regex(@"^([A-Z]\.[　 ]{0,}){2,2}").Match(analysis).Success)
                                {
                                    analysis = analysis.Substring(2).TrimStart(new char[] { '　', ' ', });
                                    if (analysis.Length > 0)
                                    {
                                        sbAnalysis.Append(analysis.Replace("\r", "").Replace("\n", ""));
                                    }
                                }
                                else
                                {
                                    if (analysis.Length > 0)
                                    {
                                        sbAnalysis.Append(analysis.Replace("\r", "").Replace("\n", ""));
                                    }
                                }

                                if (qi.IsAnswer)
                                {
                                    answerHeaderText = choiceItemHeaderText.Replace(".", "");
                                    sbAll.Append(answerHeaderText);   // 答案
                                    sbAll.Append("\t");

                                    sbAnswerLetters.Append(answerHeaderText);
                                    letterCount++;
                                    if (letterCount == 5)
                                    {
                                        sbAnswerLetters.Append(" ");
                                        letterCount = 0;
                                    }
                                }
                            }

                            sbAll.Append(sbAnalysis.ToString());  // 解析
                            sbAll.Append("\t");

                            for (int j = 0; j < cilist.Count; j++)
                            {
                                var cit = cilist[j];
                                sbAll.Append(cit);
                                if (j >= (cilist.Count - 1))
                                {
                                    sbAll.Append("\n");
                                }
                                else
                                {
                                    sbAll.Append("\t");
                                }
                            }

                            break;
                        }
                }
            }
        }

        /// <summary>
        /// 提取单选题成问卷星导入模板。
        /// </summary>
        public static void ExportQuestionsForWenJuanXing(ref List<Question> questions, out StringBuilder sbAll)
        {
            sbAll = new StringBuilder();
            var sbAnswerLetters = new StringBuilder();

            //这两个用于学生版。
            var trimChars = new char[] { '\r', '\n', ' ', '　', '\t', };
            for (int indexOfQuestion = 0; indexOfQuestion < questions.Count; indexOfQuestion++)
            {
                var q = questions[indexOfQuestion];

                switch (q.Type)
                {
                    case QuestionType.Judge:
                        {
                            //先需要混淆下顺序，否则会总选A了。
                            int[] randomArray = L.GetRandomIntArray(q.ChoiceItems.Count);
                            for (int i = 0; i < randomArray.Length; i++)
                            {
                                var qi = q.ChoiceItems[i];
                                qi.OrderNumber = randomArray[i];
                            }

                            q.ChoiceItems.Sort(new ComparsionQuestionItem());

                            string answerHeaderText = "未设置答案项";
                            var sbAnalysis = new StringBuilder();
                            List<string> cilist = new List<string>();
                            for (int i = 0; i < q.ChoiceItems.Count; i++)
                            {
                                ChoiceItem qi = q.ChoiceItems[i];
                                string choiceItemHeaderText = L.ConvertToAlpha(i + 1);
                                cilist.Add(qi.Text.Trim(trimChars));

                                string analysis = qi.AnalysisText.Replace("\r\n", "").Replace("此项", choiceItemHeaderText + "项");
                                if (new Regex(@"^([A-Z]\.[　 ]{0,}){2,2}").Match(analysis).Success)
                                {
                                    analysis = analysis.Substring(2).TrimStart(new char[] { '　', ' ', });
                                    if (analysis.Length > 0)
                                    {
                                        sbAnalysis.Append(analysis.Replace("\r", "").Replace("\n", ""));
                                    }
                                }
                                else
                                {
                                    if (analysis.Length > 0)
                                    {
                                        sbAnalysis.Append(analysis.Replace("\r", "").Replace("\n", ""));
                                    }
                                }

                                if (qi.IsAnswer)
                                {
                                    answerHeaderText = choiceItemHeaderText.Replace(".", "");
                                }
                            }

                            string title = q.TitleString.Replace("\\_", "_");

                            //根据title生成段落。
                            int startBracket, endBracket;
                            startBracket = title.IndexOf("【");
                            endBracket = title.IndexOf("】");
                            if (startBracket < 0 || endBracket < 0)
                                break;

                            string titleText = title.Substring(0, startBracket) + "（" + answerHeaderText + "）" + title.Substring(endBracket + 1);
                            titleText = titleText.Trim(trimChars);
                            sbAll.Append((indexOfQuestion + 1).ToString());
                            sbAll.Append("．");
                            sbAll.Append(titleText);   // 题干
                            if (answerHeaderText == "正确")
                            {
                                sbAll.Append("[对]\n");
                            }
                            else
                            {
                                sbAll.Append("[错]\n");
                            }

                            sbAll.Append("解析：" + sbAnalysis.ToString().Replace("\r", "").Replace("\n", "") + "\n");
                            break;
                        }
                    case QuestionType.Choice:
                        {
                            //先需要混淆下顺序，否则会总选A了。
                            int[] randomArray = L.GetRandomIntArray(q.ChoiceItems.Count);
                            for (int i = 0; i < randomArray.Length; i++)
                            {
                                var qi = q.ChoiceItems[i];
                                qi.OrderNumber = randomArray[i];
                            }

                            q.ChoiceItems.Sort(new ComparsionQuestionItem());

                            string answerHeaderText = "未设置答案项";
                            var sbAnalysis = new StringBuilder();
                            List<string> cilist = new List<string>();
                            for (int i = 0; i < q.ChoiceItems.Count; i++)
                            {
                                ChoiceItem qi = q.ChoiceItems[i];
                                string choiceItemHeaderText = L.ConvertToAlpha(i + 1);
                                cilist.Add(qi.Text.Trim(trimChars));

                                string analysis = qi.AnalysisText.Replace("\r\n", "").Replace("此项", choiceItemHeaderText + "项");
                                if (new Regex(@"^([A-Z]\.[　 ]{0,}){2,2}").Match(analysis).Success)
                                {
                                    analysis = analysis.Substring(2).TrimStart(new char[] { '　', ' ', });
                                    if (analysis.Length > 0)
                                    {
                                        sbAnalysis.Append(analysis.Replace("\r", "").Replace("\n", ""));
                                    }
                                }
                                else
                                {
                                    if (analysis.Length > 0)
                                    {
                                        sbAnalysis.Append(analysis.Replace("\r", "").Replace("\n", ""));
                                    }
                                }

                                if (qi.IsAnswer)
                                {
                                    answerHeaderText = choiceItemHeaderText.Replace(".", "");
                                }
                            }

                            string title = q.TitleString.Replace("\\_", "_");

                            //根据title生成段落。
                            int startBracket, endBracket;
                            startBracket = title.IndexOf("【");
                            endBracket = title.IndexOf("】");
                            if (startBracket < 0 || endBracket < 0)
                                break;

                            string titleText = title.Substring(0, startBracket) + "（" + answerHeaderText.Replace("．", "") + "）" + title.Substring(endBracket + 1);
                            titleText = titleText.Trim(trimChars);

                            sbAll.Append((indexOfQuestion + 1).ToString());
                            sbAll.Append("．");
                            sbAll.Append(titleText);   // 题干
                            sbAll.Append("[单选题]\n");

                            for (int j = 0; j < cilist.Count; j++)
                            {
                                var cit = cilist[j];
                                sbAll.Append(L.ConvertToAlpha(j + 1));
                                sbAll.Append(cit);
                                sbAll.Append("\n");
                            }
                            sbAll.Append("解析：" + sbAnalysis.ToString().Replace("\r", "").Replace("\n", "") + "\n");
                            break;
                        }
                }
            }
        }
        /// <summary>
        /// 提取单选题成赛事星导入模板。
        /// </summary>
        public static void ExportQuestionsForJianDaoYun(ref List<Question> questions, out StringBuilder sbAll, out StringBuilder sbAnswer)
        {
            sbAll = new StringBuilder();
            sbAnswer = new StringBuilder();
            var sbAnswerLetters = new StringBuilder();
            var sbTitle = new StringBuilder();
            var sbs = new List<StringBuilder>();

            var trimChars = new char[] { '\r', '\n', ' ', '　', '\t', };
            for (int indexOfQuestion = 0; indexOfQuestion < questions.Count; indexOfQuestion++)
            {
                var q = questions[indexOfQuestion];
                switch (q.Type)
                {
                    case QuestionType.Judge:
                    case QuestionType.Choice:
                        {
                            string title = q.TitleString.Replace("\\_", "_");

                            //根据title生成段落。
                            int startBracket, endBracket;
                            startBracket = title.IndexOf("【");
                            endBracket = title.IndexOf("】");

                            if (startBracket < 0 || endBracket < 0) break;

                            string titleText = title.Substring(0, startBracket) + "（　）" + title.Substring(endBracket + 1);
                            titleText = titleText.Trim(trimChars);

                            sbTitle.Append((indexOfQuestion + 1).ToString());
                            sbTitle.Append("．");
                            sbTitle.Append(titleText);
                            sbTitle.Append("\t");

                            //添加各选项

                            //先需要混淆下顺序，否则会总选A了。
                            int[] randomArray = L.GetRandomIntArray(q.ChoiceItems.Count);
                            for (int i = 0; i < randomArray.Length; i++)
                            {
                                var qi = q.ChoiceItems[i];
                                qi.OrderNumber = randomArray[i];
                            }

                            q.ChoiceItems.Sort(new ComparsionQuestionItem());

                            if (sbs.Count < q.ChoiceItems.Count)
                            {
                                var cn = q.ChoiceItems.Count - sbs.Count;
                                for (int i = 1; i <= cn; i++)
                                {
                                    sbs.Add(new StringBuilder());
                                }
                            }

                            for (int i = 0; i < q.ChoiceItems.Count; i++)
                            {
                                ChoiceItem qi = q.ChoiceItems[i];
                                string choiceItemHeaderText = L.ConvertToAlpha(i + 1);
                                sbs[i].Append(choiceItemHeaderText);
                                sbs[i].Append(qi.Text.Trim(trimChars));
                                sbs[i].Append("\t");

                                if (qi.IsAnswer)
                                {
                                    sbAnswer.Append(choiceItemHeaderText.Replace("．", ""));
                                }
                            }
                            break;
                        }
                }
            }

            var trimTab = new char[] { '\t', };
            sbAll.Append(sbTitle.ToString().Trim(trimTab));
            sbAll.Append("\n");

            foreach (var sbss in sbs)
            {
                sbAll.Append(sbss.ToString().Trim(trimTab));
                sbAll.Append("\n");
            }
        }

        /// <summary>
        /// 抽取所有与试题相关的文本行。
        /// </summary>
        /// <param name="src">源文本。</param>
        /// <returns>返回源文本中与试题相关的所有文本行。</returns>
        public static string OutLineExamsText(string src)
        {
            if (string.IsNullOrEmpty(src)) return "";

            var lines = src.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            StringBuilder sb = new StringBuilder();
            foreach (var l in lines)
            {
                if (Question.IsExamTextLine(l) || CustomMarkdownSupport.IsImageLinkLine(l) || l.Contains("｜") || l.Contains("|"))
                {
                    sb.Append(l);
                    sb.Append("\r\n");
                }
            }

            return sb.ToString();
        }
    }

    public class QuestionList : List<Question>
    {
        public string FilePath { get; set; }
    }

}
